package link.at17.mid.tushare.data.crawler.tushare;


import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;

import link.at17.mid.tushare.component.OkHttpClientProvider;
import link.at17.mid.tushare.system.config.SystemConfig;
import link.at17.mid.tushare.system.util.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

@Slf4j
@Component
public class TushareClient {
    
    private static final String TUSHARE_URL = "http://api.tushare.pro";
    
    private static String getToken() {
        SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
        String token = systemConfig.getTushareToken();
        if (!StringUtils.isEmpty(token) && Pattern.matches("^[0-9a-f]{56}$", token)) {
            return token;
        }
        else {
            return "6f284d9246bad80c3eff946f3ecae8442072b1e60652785f66007509";
        }
    }
    
    /**
     * 返回原始查询结果
     * @param tr
     * @return
     */
    public static JSONObject query(TushareRequestBody tr) throws IOException, JSONException {
        OkHttpClient okHttpClient = OkHttpClientProvider.getInstance();
        tr.setToken(getToken());
        Request request = new Request.Builder()
                .url(TUSHARE_URL)
                .post(
                    RequestBody.create(
                        tr.toJSONString(),
                        MediaType.parse("application/json; charset=utf-8")))
                .build();

        final Call call = okHttpClient.newCall(request);
        Response response = call.execute();
        JSONObject result = JSONObject.parseObject(response.body().string());
        if (result.get("data") == null) {
            response.close();
            throw new TushareException(result.getString("msg"));
        }
        response.close();
        return result.getJSONObject("data");
    }
    
    /**
     * 返回封装查询结果
     * @param tr
     * @return null 说明请求出错，EmptyList 说明请求成功但结果列表为空
     * @throws IOException 
     * @throws JSONException 
     */
    public static List<JSONObject> queryList(TushareRequestBody tr) throws JSONException, IOException {
        JSONObject jo = query(tr);
        if (jo == null) {
            return null;
        }
        List<JSONObject> result = new ArrayList<JSONObject>();
        JSONArray fields = jo.getJSONArray("fields");
        JSONArray items = jo.getJSONArray("items");
        int fieldsCount = fields.size();
        for (Object o : items) {
            JSONArray ja = (JSONArray)o;
            JSONObject item = new JSONObject();
            for (int i = 0; i < fieldsCount; i++) {
                item.put(fields.getString(i), ja.get(i));
            }
            result.add(item);
        }
        return result;
    }
    
    public static void main(String[] args) {
        /*
         * 测试获取股票列表
        TushareRequestBody request = 
            new TushareRequestBody("stock_basic")
                .addParam("list_status", "L")
                .addFields("ts_code,name,area,industry,market,list_date,delist_date");
        System.out.println(query(request).toJSONString());
        */

        TushareRequestBody request = 
            new TushareRequestBody("daily")
                .addParam("start_date", "19910101")
                .addParam("end_date", "20180101")
                .addFields("ts_code");
        Queue<TushareRequestBody> requestQueue = new LinkedList<>();
        requestQueue.add(request);
        requestQueue.add(request.clone().addParam("start_date", "fuck").addField("fuckyou"));
        // 测试 clone 是否成功
        requestQueue.forEach(System.out::println);
    }
}
