package top.octopusyan.http.request;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import okhttp3.Headers;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import top.octopusyan.http.HttpLog;
import top.octopusyan.http.api.RequestApi;
import top.octopusyan.http.exception.*;
import top.octopusyan.http.response.BaseRest;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;


/**
 * @author octopus yan
 * @email octopus_yan@foxmail.com
 * @description 请求处理类
 * @create 2021-07-23 11:55:26
 */
public final class RequestHandler implements IRequestHandler {

    @Override
    public Request requestStart(RequestApi api, Request request) {
        return IRequestHandler.super.requestStart(api, request);
    }

    @Override
    public Object requestSucceed(RequestApi api, Response response, Type type) throws Exception {
        if (Response.class.equals(type)) {
            return response;
        }

        if (!response.isSuccessful()) {
            // 返回响应异常
            throw new ResponseException("服务器响应异常，responseCode：" + response.code() + "，message：" + response.message(), response);
        }

        if (Headers.class.equals(type)) {
            return response.headers();
        }

        ResponseBody body = response.body();
        if (body == null) {
            return null;
        }

        if (InputStream.class.equals(type)) {
            return body.byteStream();
        }

        String text;
        try {
            text = body.string();
        } catch (IOException e) {
            // 返回结果读取异常
            throw new DataException("数据解析异常", e);
        }

        // 打印这个 Json 或者文本
        HttpLog.json(text);

        if (String.class.equals(type)) {
            return text;
        }

        if (JSONObject.class.equals(type)) {
            try {
                // 如果这是一个 JSONObject 对象
//                return new JSONObject(text);
                return JSON.parseObject(text);
            } catch (JSONException e) {
                throw new DataException("数据解析异常", e);
            }
        }

        if (JSONArray.class.equals(type)) {
            try {
                // 如果这是一个 JSONArray 对象
//                return new JSONArray(text);
                return JSON.parseArray(text);
            } catch (JSONException e) {
                throw new DataException("数据解析异常", e);
            }
        }

        final Object result;

        try {
//            result = GsonFactory.getSingletonGson().fromJson(text, type);
            JSONObject jsonObject = JSONObject.parseObject(text);
            result = jsonObject.toJavaObject(type);
//            result = new Gson().fromJson(text, type);
        } catch (JSONException e) {
            // 返回结果读取异常
            throw new DataException("数据解析异常", e);
        }

        if (result instanceof BaseRest) {
            BaseRest model = (BaseRest) result;

            if (model.isRequestSucceed()) {
                // 代表执行成功
                return result;
            }

            if (model.isTokenFailure()) {
                // 代表登录失效，需要重新登录
                throw new TokenException("登录失效，请重新登录");
            }

            // 代表执行失败
            throw new ResultException(response.request().body() + "\r\n" + model.getMsg(), model);
        }
        return result;
    }

    @Override
    public  <Param, Result> Exception requestFail(RequestApi<Param, Result> api, Exception e) {
        // 判断这个异常是不是自己抛的
        if (e instanceof HttpException) {
            if (e instanceof TokenException) {
                // TODO 登录信息失效
            }
            return e;
        }

        if (e instanceof SocketTimeoutException) {
            return new TimeoutException("服务器请求超时，请稍后再试", e);
        }

        if (e instanceof UnknownHostException) {
            // 利用百度服务器地址，判断网络是否连接
            if (!isReachable("14.215.177.38")) {
                // 没有连接就是网络异常
                return new NetworkException("请求失败，请检查网络设置", e);
            }

            // 有连接就是服务器的问题
            return new ServerException("服务器连接异常，请稍后再试", e);
        }

        if (e instanceof IOException) {
            //e = new CancelException(context.getString(R.string.http_request_cancel), e);
            return new CancelException("", e);
        }

        return new HttpException(e.getMessage(), e);
    }

    /**
     * 传入需要连接的IP，返回是否连接成功
     */
    public static boolean isReachable(String remoteInetAddr) {
        boolean reachable = false;
        try {
            InetAddress address = InetAddress.getByName(remoteInetAddr);
            reachable = address.isReachable(5000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return reachable;
    }
}