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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import net.sf.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpUtil {

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

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

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

    public static final String APPLICATION_JSON = "application/json;charset=utf-8";

    public static final String METHOD_POST = "POST";

    public static final String ACCESS_TOKEN = "Access-Token";

    public static final String TIMESTAMP = "timestamp";

    public static final String ROOT_ORG_ID = "rootOrgId";

    public static final String APP_ID = "appId";

    public static final String ERROR_CODE = "EX-101444";

    // 请求地址
    protected String uri = null;

    protected String secretKey = null;

    protected String appId = null;

    protected String rootOrgId = null;

    public HttpUtil(String uri, String secretKey, String appId, String rootOrgId) {
        this.uri = uri;
        this.secretKey = secretKey;
        this.appId = appId;
        this.rootOrgId = rootOrgId;
    }

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

        try {

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

            long timestamp = System.currentTimeMillis();

            StringBuilder sb = new StringBuilder();
            sb.append(rootOrgId).append(appId).append(timestamp).append(secretKey);

            byte[] bytes = SHA256.encode(sb.toString());
            String accessToken = ByteUtil.toHexAscii(bytes);

            conn.setRequestMethod(METHOD_POST);
            conn.setRequestProperty(CONTENT_TYPE, APPLICATION_JSON);
            // conn.setRequestProperty("accept", "application/json");
            // 设置鉴权
            conn.setRequestProperty(ACCESS_TOKEN, accessToken);
            // 机构
            conn.setRequestProperty(APP_ID, appId);
            conn.setRequestProperty(ROOT_ORG_ID, rootOrgId);
            // 设置时间
            conn.setRequestProperty(TIMESTAMP, String.valueOf(timestamp));
            // 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) {
                os = conn.getOutputStream();
                os.write(datas.getBytes());
                os.flush();
            }

            result = getResult(conn);
            JSONObject message = JSONObject.fromObject(result);
            message.accumulate("code", "");
            result = message.toString();
        } catch (Exception e) {
            // 操作失败
            log.error("Http connection error!", e);
            e.printStackTrace();
            return e.getMessage();
        } finally {
            try {
                if (os != null) {
                    os.close();
                    os = null;
                }
                if (is != null) {
                    is.close();
                    is = null;
                }
            } catch (IOException e) {
                log.error("Http 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 static void main(String[] args) throws IOException {
        // JSONObject json = new JSONObject();
        // json.accumulate("examId", 240);
        // json.accumulate("subjectCode", "CJFX18");
        // String test =
        // "https://ecs-test.ea100.com.cn/api/exchange/outer/question/getSubjectivePaperStruct";
        String dev = "https://ucass.exam-cloud.cn/api/exchange/outer/question/getSubjectivePaperStruct";
        long start = System.currentTimeMillis();
        JSONObject json = new JSONObject();
        json.accumulate("examId", 3710);
        HttpUtil subjectHttp = new HttpUtil(dev, "jfapejf8eif%ijipa^ii8k3jii", "ucass", "17796");
        String subjectJson = subjectHttp.httpAction(null, json.toString());
        System.out.println(subjectJson);
        // ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        // IOUtils.copy(new
        // ByteArrayInputStream(subjectJson.getBytes(StandardCharsets.UTF_8)),
        // buffer);
        // byte[] data = buffer.toByteArray();
        // File target = new File("/Users/ting.yin/Desktop/test123.json");
        // target.getParentFile().mkdirs();
        // FileOutputStream ous = new FileOutputStream(target);
        // ous.write(data);
        // IOUtils.closeQuietly(ous);
        // HttpUtil subjectHttp = new HttpUtil(
        // "http://iepcc-ps.ecs.qmth.com.cn:80/api/exchange/outer/question/getSubjectivePaperStruct",
        // "Fu234234CK!fsd9f0", "EPCC", "16923");
        // String subjectJson = subjectHttp.httpAction(null, json.toString());
        // System.out.println(subjectJson);

        // HttpUtil paperHttp = new
        // HttpUtil();
        // String paper = paperHttp.httpAction(null, json.toString());
        // System.out.println(paper);

        // HttpUtil studentHttp = new HttpUtil(
        // "https://ecs-test.ea100.com.cn/api/exchange/outer/question/getSubjectiveQuestion",
        // "123456", "11",
        // "17128");
        // json.accumulate("startId", 0);
        // json.accumulate("size", 1);
        // String studentJson = studentHttp.httpAction(null, json.toString());
        // System.out.println(studentJson);
        // long end = System.currentTimeMillis();
        // System.out.println(end - start);
    }
}
