package com.sdtool.common.api;

import com.sdtool.common.base.BaseService;
import com.sdtool.common.datas.LocalTypeToken;
import com.dySweetFishPlugin.sql.DBService;
import com.dySweetFishPlugin.tool.lang.ThreadFactoryWithNamePrefix;
import com.sweetfish.convert.json.JsonConvert;
import com.sweetfish.service.RetResult;
import com.sweetfish.source.PageFlipper;
import com.sweetfish.util.AnyValue;
import com.sweetfish.util.AutoLoad;
import org.rex.RMap;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.*;

/**
 * Created by jlutt on 2022-08-18
 *
 * @author jlutt
 */
@AutoLoad(false)
public class TypeTokenConvertService extends BaseService {

    @Resource
    JsonConvert jsonConvert;

    @Resource
    DBService dbService;

    private ExecutorService sqlExecutor;

    @Override
    public void init(AnyValue config) {
        super.init(config);
        LocalTypeToken.init();
        sqlExecutor = new ThreadPoolExecutor(
                2, //corePoolSize 线程池维护线程的最少数量
                8, // maxPoolSize 线程池维护线程的最大数量
                60, //keepAliveSeconds 线程池维护线程所允许的空闲时间
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(Integer.MAX_VALUE),
                new ThreadFactoryWithNamePrefix("[统计查询SQL线程池]"));
    }

    @Override
    public void destroy(AnyValue config) {
        sqlExecutor.shutdown();
    }

    public List<String> convertListString(String json) {
        return jsonConvert.convertFrom(LocalTypeToken.listString, json);
    }

    @SuppressWarnings("rawtypes")
    public RetResult<List<RMap>> executeSQL(String sqlData, String sqlCollection, PageFlipper pageFlipper, String dataSourceId) {
        CompletableFuture<List<RMap>> futureData = CompletableFuture.supplyAsync(() -> dbService.getMapList(dataSourceId, sqlData, pageFlipper), sqlExecutor);
        CompletableFuture<RMap> futureCollection = CompletableFuture.supplyAsync(() -> dbService.getMap(dataSourceId, sqlCollection), sqlExecutor);
        CompletableFuture<Void> sqlFuture = CompletableFuture.allOf(futureData, futureCollection);
        try {
            sqlFuture.get(20, TimeUnit.SECONDS);
            return RetResult.<List<RMap>>successT().result(futureData.get()).attachRMap(futureCollection.get()).page(pageFlipper);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            logger.error(e.getMessage(), e);
            return RetResult.<List<RMap>>errorT().retinfo(e.getMessage());
        }
    }

    @SuppressWarnings("rawtypes")
    public RetResult<List<RMap>> executeSQL(String sqlData, String sqlCollection, String dataSourceId) {
        CompletableFuture<List<RMap>> futureData = CompletableFuture.supplyAsync(() -> dbService.getMapList(dataSourceId, sqlData), sqlExecutor);
        CompletableFuture<RMap> futureCollection = CompletableFuture.supplyAsync(() -> dbService.getMap(dataSourceId, sqlCollection), sqlExecutor);
        CompletableFuture<Void> sqlFuture = CompletableFuture.allOf(futureData, futureCollection);
        try {
            sqlFuture.get(20, TimeUnit.SECONDS);
            return RetResult.<List<RMap>>successT().result(futureData.get()).attachRMap(futureCollection.get());
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            logger.error(e.getMessage(), e);
            return RetResult.<List<RMap>>errorT().retinfo(e.getMessage());
        }
    }
}
