package com.bcxin.Infrastructures.components;

import com.bcxin.Infrastructures.exceptions.BadTenantException;
import com.bcxin.Infrastructures.utils.URLUtil;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Component;

import javax.net.ssl.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public interface WebFileProvider {
    InputStream download(String path);

    @Component
    static class WebFileProviderImpl implements WebFileProvider
    {
        @Override
        public InputStream download(String path) {
            HttpURLConnection connection = null;
            try {
                path = URLUtil.encode(path);
                URL url = new URL(path);
                if(path.startsWith("https")) {
                    HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
                    trustAllHosts(https);

                    https.setHostnameVerifier(new HostnameVerifier() {
                        @Override
                        public boolean verify(String s, SSLSession sslSession) {
                            return true;
                        }
                    });
                    connection = https;
                }else {
                    connection = (HttpURLConnection) url.openConnection();
                }
                connection.setRequestMethod("GET");
                connection.setDoInput(true);
                connection.setDoInput(true);
                connection.setRequestProperty("Accept-Charset", "utf-8");
                connection.setConnectTimeout(20 * 1000);
                final ByteArrayOutputStream output = new ByteArrayOutputStream();

                InputStream inputStream = connection.getInputStream();
                IOUtils.copy(inputStream, output);
                return new ByteArrayInputStream(output.toByteArray());
            } catch (Exception e) {
                e.printStackTrace();

                throw new BadTenantException(String.format("文件(%s)下载失败! 失败原因=%s", path, e.getMessage()));
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }
        }

        private static SSLSocketFactory trustAllHosts(HttpsURLConnection connection) {
            SSLSocketFactory oldFactory = connection.getSSLSocketFactory();
            try {
                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                SSLSocketFactory newFactory = sc.getSocketFactory();
                connection.setSSLSocketFactory(newFactory);
            } catch (Exception ex) {
                ex.toString();
            }

            return oldFactory;
        }

        private static final TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }
                }
        };
    }
}
