package cn.com.qmth.stmms.biz.utils;

import cn.com.qmth.stmms.biz.school.model.School;
import cn.com.qmth.stmms.common.signature.SignatureInfo;
import cn.com.qmth.stmms.common.signature.SignatureType;
import com.qmth.boot.tools.models.ByteArray;
import com.qmth.boot.tools.ssl.AllAcceptSSLContext;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SolarHttpUtil {

    private static Logger log = LoggerFactory.getLogger(SolarHttpUtil.class);

    /**
     * 默认的编码格式
     */
    public static final String DEFAULT_CHARSET = "UTF-8";

    public static final String CONTENT_TYPE = "Content-Type";

    public static final String APPLICATION_JSON = "application/x-www-form-urlencoded;charset=utf-8";

    public static final String METHOD_POST = "POST";

    public static final String AUTH = "Authorization";

    protected String host = null;

    protected String uri = null;

    protected String accessKey = null;

    protected String accessSecret = null;

    public SolarHttpUtil(String accessKey, String accessSecret, String host, String uri) {
        this.accessKey = accessKey;
        this.accessSecret = accessSecret;
        this.uri = uri;
        this.host = host;
    }

    /**
     * @param params
     *            headers参数
     * @param datas
     *            requestParams参数
     * @return
     */
    public String httpAction(Map<String, String> params, Map<String, Object> datas) {
        String result = null;
        HttpsURLConnection conn = null;
        OutputStream os = null;
        InputStream is = null;

        try {

            // 获取链接
            URL url = new URL(host + uri);
            conn = (HttpsURLConnection) url.openConnection();

            conn.setRequestMethod(METHOD_POST);
            conn.setRequestProperty(CONTENT_TYPE, APPLICATION_JSON);
            // 设置鉴权
            long time = System.currentTimeMillis();
            String signature = SignatureInfo.build(SignatureType.SECRET, METHOD_POST, uri, time, accessKey,
                    accessSecret);
            conn.setRequestProperty(AUTH, signature);
            conn.setRequestProperty("time", String.valueOf(time));
            // ssl
            SSLContext context = SSLContext.getInstance("SSL", "SunJSSE");
            TrustManager[] tm = new TrustManager[] { new X509TrustManager() {

                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            } };
            // 初始化
            context.init(null, tm, new java.security.SecureRandom());
            // 获取SSLSocketFactory对象
            SSLSocketFactory ssf = context.getSocketFactory();
            conn.setSSLSocketFactory(ssf);

            conn.setUseCaches(false);
            conn.setDoOutput(true);

            // 设置额外的参数
            if (params != null && !params.isEmpty()) {

                for (Map.Entry<String, String> param : params.entrySet()) {
                    conn.setRequestProperty(param.getKey(), param.getValue());
                }
            }
            // 创建链接
            conn.connect();
            // 设置请求参数
            if (datas != null) {
                StringBuilder sb = new StringBuilder();
                for (Map.Entry<String, Object> data : datas.entrySet()) {
                    sb.append(data.getKey()).append("=").append(data.getValue()).append("&");
                }
                os = conn.getOutputStream();
                os.write(sb.toString().getBytes());
                os.flush();
            }

            result = getResult(conn);
        } catch (Exception e) {
            // 操作失败
            log.error("Solar api connection error!", e);
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (os != null) {
                    os.close();
                    os = null;
                }
                if (is != null) {
                    is.close();
                    is = null;
                }
            } catch (IOException e) {
                log.error("Solar api connection error!", e);
            }

            if (conn != null) {
                conn.disconnect();
                conn = null;
            }
        }

        return result;
    }

    /**
     * 获得连接请求的返回数据
     *
     * @param conn
     * @return 字符串
     */
    private String getResult(HttpURLConnection conn) throws IOException {

        StringBuilder text = new StringBuilder();

        InputStream is = null;
        InputStreamReader sr = null;
        BufferedReader br = null;

        int code = conn.getResponseCode();

        try {
            is = code >= 400 ? conn.getErrorStream() : conn.getInputStream();

            sr = new InputStreamReader(is, DEFAULT_CHARSET);
            br = new BufferedReader(sr);

            char[] chars = new char[4096];
            int length = 0;

            while ((length = br.read(chars)) != -1) {
                text.append(chars, 0, length);
            }
        } finally {
            if (br != null) {
                br.close();
                br = null;
            }
            if (sr != null) {
                sr.close();
                sr = null;
            }
            if (is != null) {
                is.close();
                is = null;
            }
        }
        if (code >= 400) {
            throw new IOException(text.toString());
        }
        return text.toString();
    }

    public boolean getAPP() {
        try {
            String str = this.httpAction(null, null);
            JSONObject json = JSONObject.fromObject(str);
            @SuppressWarnings("unused")
            Integer id = json.getInt("id");
            return true;
        } catch (Exception e) {
            log.error("Solar api connection error!", e);
            return false;
        }
    }

    public List<School> getOrgs() {
        List<School> schools = new ArrayList<School>();
        int pageNumber = 1;
        int pageSize = 100;
        while (pageNumber != 0) {
            Map<String, Object> datas = new HashMap<String, Object>();
            datas.put("pageNumber", pageNumber);
            datas.put("pageSize", pageSize);
            String str = this.httpAction(null, datas);
            JSONArray orgArray = JSONArray.fromObject(str);
            if (orgArray.size() == pageSize) {
                pageNumber++;
            } else {
                pageNumber = 0;
            }
            for (int i = 0; i < orgArray.size(); i++) {
                JSONObject org = orgArray.getJSONObject(i);
                School school = new School();
                school.setAccessKey(org.getString("accessKey"));
                school.setAccessSecret(org.getString("accessSecret"));
                school.setCode(org.getString("code"));
                school.setName(org.getString("name"));
                school.setLogoUrl(org.getString("logo"));
                school.setEnable(true);
                school.setDoubleTrack(false);
                school.setGroupDeleteCheck(false);
                schools.add(school);
            }
        }

        return schools;
    }

    public static void main(String[] args) throws Exception {
        // SolarHttpUtil orgUtil = new
        // SolarHttpUtil("7bbdc11570bc474dbf50e0d4a5dff328",
        // "IOodRvbp2LspJTHOScgB7Yx8MRloMpyl", "https://solar.qmth.com.cn",
        // "/api/open/org/query");
        //
        // String str = orgUtil.httpAction(null, null);
        // System.out.println(str);
        // int pageNumber = 1;
        // int pageSize = 1;
        //
        // while (pageNumber != 0) {
        // Map<String, Object> datas = new HashMap<String, Object>();
        // datas.put("pageNumber", pageNumber);
        // datas.put("pageSize", pageSize);
        // String str = orgUtil.httpAction(null, datas);
        // JSONArray orgArray = JSONArray.fromObject(str);
        // if (orgArray.size() == pageSize) {
        // pageNumber++;
        // } else {
        // pageNumber = 0;
        // }
        // System.out.println(str);
        // }
        String server = "https://solar.qmth.com.cn";
        String uri = "/api/open/app/info";
        String accessKey = "7bbdc11570bc474dbf50e0d4a5dff328";
        String accessSecret = "IOodRvbp2LspJTHOScgB7Yx8MRloMpyl";
        HttpsURLConnection conn = (HttpsURLConnection) new URL(server + uri).openConnection();
        conn.setSSLSocketFactory(AllAcceptSSLContext.get().getSocketFactory());
        conn.setHostnameVerifier((s, sslSession) -> true);
        conn.setInstanceFollowRedirects(false);
        conn.setRequestMethod(METHOD_POST);
        conn.setConnectTimeout(5000);
        conn.setReadTimeout(5000);
        // 设置鉴权
        long time = System.currentTimeMillis();
        String signature = SignatureInfo.build(SignatureType.SECRET, METHOD_POST, uri, time, accessKey, accessSecret);
        conn.setRequestProperty(AUTH, signature);
        conn.setRequestProperty("time", String.valueOf(time));
        InputStream ins = conn.getInputStream();
        System.out.println(ByteArray.fromInputStream(ins).toString());
        ins.close();
    }
}
