package cn.com.ty.lift.business.common.http;

import cn.com.ty.lift.business.framework.BusinessBasicException;
import com.ning.http.client.Response;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Objects;

/**
 * Created by xp-zhao@logictech.cn
 * Create on 16/2/19^ 上午10:24
 * Remark Http request class , if parameters set values, data will't send
 */
@Slf4j
public class HttpClient extends BasicHttpClient {

    private Response response;

    private BusinessBasicException businessException;

    public HttpClient() {
    }

    public static HttpClient getInstance() {
        HttpClient HttpClient = new HttpClient();
        HttpClient.businessException = new BusinessBasicException();
        return HttpClient;
    }

    public static HttpClient getInstance(BusinessBasicException exception) {
        HttpClient HttpClient = new HttpClient();
        HttpClient.businessException = exception;
        return HttpClient;
    }

    /**
     * @see HttpClient#send(String, String, Map, Map)
     */
    public HttpClient send(final String method, final String url, final Map<String, Object> params) {
        send(GET, url, params, formHeaders);
        return this;
    }

    /**
     * @see HttpClient#send(String, String, Map, Map)
     */
    public HttpClient send(final String url, final Map<String, Object> params) {
        send(POST, url, params, formHeaders);
        return this;
    }

    /**
     * @see HttpClient#sends(String, String, Map, Map)
     */
    public HttpClient send(final String url, final Map<String, Object> params, final Map<String, Object> headers) {
        send(POST, url, params, headers);
        return this;
    }

    /**
     * @see BasicHttpClient#sends(String, String, Map, Map)
     */
    public HttpClient send(final String method, final String url, final Map<String, Object> params, final Map<String, Object> headers) {
        //write info log4j
        log.info("method:" + method + "\n" + "url:" + url + "\n" + "parameter:" + params + "\n" + "headers" + headers + "\n");
        try {
            response = super.sends(method, url, params, headers);
            checkResponse();
        } catch (Exception ex) {
            businessException.msg = ex.toString();
            throw businessException;
        }
        return this;
    }

    public void checkResponse() throws IOException {
        if (response == null) {
            log.error("response is null\n");
            businessException.msg = "返回response为null";
            throw businessException;
        }

        if (!Objects.equals(response.getStatusCode(), 200)) {
            log.error("response status:" + response.getStatusCode() + "\n");
            businessException = businessException.getExceptionType(getStatus());
            //扩展异常错误提示信息
            //businessException.msg = "返回状态码错误:" + response.getStatusCode();
            businessException.msg = response.getResponseBody();
            throw businessException;
        }

        //write response message to file
        log.info("response:\n" + response.getResponseBody());
    }

    public <T extends Serializable> T convert(Class<T> clazz) {
        try {
            return gson.fromJson(getResponseBody(), clazz);
        } catch (Exception e) {
            log.error("json2Bean失败，错误信息：" + e, e);
            businessException = businessException.getExceptionType(500);
            businessException.msg = "json解析错误" + e;
            throw businessException;
        }
    }

    public <T extends Serializable> T convert(final Type clazz) {
        try {
            return gson.fromJson(getResponseBody(), clazz);
        } catch (Exception e) {
            log.error("json2Bean失败，错误信息：" + e, e);
            businessException = businessException.getExceptionType(500);
            businessException.msg = "json解析错误";
            throw businessException;
        }
    }

    public String getResponseBody() {
        try {
            return response.getResponseBody();
        } catch (Exception e) {
            log.error("获取ResponseBody错误:" + e);
            businessException = businessException.getExceptionType(getStatus());
            businessException.msg = "获取ResponseBody错误:" + e;
            throw businessException;
        }
    }

    public Integer getStatus() {
        return response.getStatusCode();
    }
}
