package com.cool.store.utils;

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

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * @author leoxie
 */
public class Client {

    private String url;
    private String method = "POST";
    private HashMap<String,String> header;
    private String data;
    private Integer timeout = 8000;
    private Integer maxLength = 10000;

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

    public String exec() throws IOException {

        HttpURLConnection connection = null;
        OutputStreamWriter out = null;
        BufferedReader reader = null;
        StringBuilder res = null;
        String result = null;
        Long optTime = 0L;
        InputStream is = null;

        LocalDateTime beginTime = LocalDateTime.now();

        URL url = new URL(getUrl());
        connection = (HttpURLConnection) url.openConnection();

        try {
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);

            //设置超时时间
            connection.setConnectTimeout(getTimeout());
            connection.setReadTimeout(getTimeout());

            // 设置请求方式
            connection.setRequestMethod(getMethod());
            // 设置发送数据的格式
            if (!getHeader().isEmpty()) {
                for (Map.Entry<String, String> entry : getHeader().entrySet()) {
                    connection.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }
            //发起连接
            connection.connect();

            // utf-8编码[推送提交的参数]
            if (!getData().isEmpty()) {
                out = new OutputStreamWriter(connection.getOutputStream(), StandardCharsets.UTF_8);
                out.append(getData());
                out.flush();
                out.close();
            }

            if(connection.getResponseCode() > 2000){
                is = connection.getErrorStream();
            }else{
                is = connection.getInputStream();
            }
            // 读取响应
            reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
            String line;
            res = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                res.append(line);
            }
            reader.close();

            result = res.toString();
            return result;

        }catch (Exception e){
            throw e;
        }finally {
            if (connection != null){
                connection.disconnect();
            }

            if(out != null){
                out.close();
            }

            if(reader != null){
                reader.close();
            }

//            log.info("request url is : " + getUrl());
//            log.info("request params is : " + getData());
//            if(result != null && result.length() < maxLength) {
//                log.info("response : " + result);
//            }
//            optTime = Duration.between(beginTime,LocalDateTime.now()).toMillis();
//            log.info("response time: " + optTime.toString());
        }
    }

    public String getUrl() {
        assert !url.isEmpty();
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getMethod() {
        assert !method.isEmpty();
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public HashMap<String, String> getHeader() {
        return header;
    }

    public void setHeader(HashMap<String, String> header) {
        this.header = header;
    }

    public String getData() {
        return data;
    }

    /**
     * 提交参数
     *
     * 如果是json形式，那么就是json字符串，
     * 如果是表单形式，就是name1=value1&name2=value2 的形式
     * @param data
     */
    public void setData(String data) {
        this.data = data;
    }

    public Integer getTimeout() {
        return timeout;
    }

    public void setTimeout(Integer timeout) {
        this.timeout = timeout;
    }


}
