package cn.stylefeng.team.meta.db;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.db.DbUtil;
import cn.hutool.db.Entity;
import cn.hutool.db.handler.EntityListHandler;
import cn.hutool.db.sql.SqlExecutor;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.team.meta.db.enums.DbDataExceptionEnum;
import cn.stylefeng.team.meta.db.pojo.DatabaseConfig;
import cn.stylefeng.team.meta.db.pojo.JsonDataInfo;
import cn.stylefeng.team.meta.db.pojo.query.Group;
import cn.stylefeng.team.meta.db.util.DataSourceUtil;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Getter
public abstract class BaseDataCollector {

    private final DatabaseConfig databaseConfig;

    private final DruidDataSource druidDataSource;

    public BaseDataCollector(DatabaseConfig databaseConfig) {

        if (databaseConfig == null || ObjectUtil.hasEmpty(databaseConfig.getUsername(), databaseConfig.getPassword(), databaseConfig.getJdbcUrl(), databaseConfig.getDriverClass())) {
            throw new ServiceException(DbDataExceptionEnum.PARAMETER_EMPTY);
        }

        this.databaseConfig = databaseConfig;
        this.druidDataSource = DataSourceUtil.getDruidDataSource(databaseConfig);
    }

    public List<Entity> queryDataList(String sql, Object... parameters) {

        DruidPooledConnection connection = null;

        try {

            connection = druidDataSource.getConnection();

            List<Entity> entityList = SqlExecutor.query(connection, sql, new EntityListHandler(), parameters);

            log.debug("查询结果: {} ", entityList);

            return entityList;

        } catch (SQLException e) {

            log.error("DataCollector查询失败！", e);

        } finally {

            DbUtil.close(connection);

        }

        return new ArrayList<>();
    }

    public int update(String sql, Object... parameters) {

        DruidPooledConnection connection = null;

        try {
            connection = druidDataSource.getConnection();
            return SqlExecutor.execute(connection, sql, parameters);
        } catch (SQLException e) {
            log.error("DataCollector执行更新操作失败！", e);
        } finally {
            DbUtil.close(connection);
        }

        return 0;
    }

    public List<JsonDataInfo> toJsonDataInfo(List<Entity> entityList) {
        ArrayList<JsonDataInfo> jsonDataInfos = new ArrayList<>();

        for (Entity entity : entityList) {
            JsonDataInfo jsonDataInfo = new JsonDataInfo();
            jsonDataInfo.setDataId(IdWorker.getId());
            jsonDataInfo.setDataJson(JSON.toJSONString(entity));
            jsonDataInfo.setCreateTime(new Date());
            jsonDataInfos.add(jsonDataInfo);
        }

        return jsonDataInfos;
    }

    public void close() {
        DbUtil.close(druidDataSource);
    }

    public abstract List<Entity> queryTotal(String tableName);

    public abstract Long queryTotalCount(String tableName);

    public abstract Long queryTotalCount(String tableName, Group queryCondition);

    public abstract List<JsonDataInfo> queryTotalToJson(String tableName);

    public abstract List<Entity> pageQuery(String tableName, Integer pageSize, Integer pageNo);

    public abstract List<JsonDataInfo> pageQueryToJson(String tableName, Integer pageSize, Integer pageNo);

    public abstract List<JsonDataInfo> pageQueryToJson(String tableName, Integer pageSize, Integer pageNo, Group queryCondition);

}
