package cc.smtweb.framework.core.db.cache;

import cc.smtweb.framework.core.annotation.SwCache;
import cc.smtweb.framework.core.cache.AbstractCache;
import cc.smtweb.framework.core.cache.CacheManager;
import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.vo.ModelField;
import cc.smtweb.framework.core.db.vo.ModelProject;
import cc.smtweb.framework.core.db.vo.ModelTable;
import cc.smtweb.framework.core.util.CommUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

/**
 * Created by Akmm at 2022/1/12 18:34
 */
@SwCache(ident = "ASP_MODEL_TABLE", title = "数据库表定义")
public class ModelTableCache extends AbstractCache<ModelTable> {
    private final static String mk = "k";
    private final static String md = "d";
    private final static String mc = "c";
    private final static String mk_link = "l";

    public static ModelTableCache getInstance() {
        return CacheManager.getIntance().getCache(ModelTableCache.class);
    }

    public ModelTableCache() {
        regMap(mk, k -> k.getName().toUpperCase());
        regList(md, k -> String.valueOf(k.getDbId()));
        regList(mc, k -> String.valueOf(k.getMcId()));
        regListEx(mk_link, k -> {
            Set<String> list = new HashSet<>();
            for (ModelField field : k.getFields()) {
                if (field.getLink() > 0) list.add(String.valueOf(field.getLink()));
            }
            return list.toArray(new String[list.size()]);
        });
//        regList(mf, k-> k.get);
    }

    @Override
    protected String getId(ModelTable bean) {
        return String.valueOf(bean.getId());
    }

    @Override
    protected List<ModelTable> loadAll() {
        String sql;
        if (!StringUtils.isEmpty(SwConsts.SysParam.RUN_PROJECTS)) {
            sql = " inner join " + ModelProject.ENTITY_NAME + " on tb_prj_id=prj_id where prj_module in (" + CommUtil.getSqlInStr(SwConsts.SysParam.RUN_PROJECTS.split(",")) + ")";
        } else sql = "";
        return DbEngine.getInstance().query("SELECT\n" +
                "t.tb_id,\n" +
                "t.tb_prj_id,\n" +
                "t.tb_mc_id,\n" +
                "t.tb_db_id,\n" +
                "t.tb_extends,\n" +
                "t.tb_name,\n" +
                "t.tb_title,\n" +
                "t.tb_abbr,\n" +
                "t.tb_type,\n" +
                "t.tb_need_cache,\n" +
                "t.tb_content,\n" +
                "t.tb_create_uid,\n" +
                "t.tb_update_uid,\n" +
                "t.tb_create_at,\n" +
                "t.tb_update_at\n" +
                "from asp_model_table t\n" + sql, new ResultSetExtractor<List<ModelTable>>() {
            @Override
            public List<ModelTable> extractData(ResultSet rs) throws SQLException, DataAccessException {
                List<ModelTable> list = new ArrayList<>();
                while (rs.next()) {
                    ModelTable table = new ModelTable();
                    list.add(table);
                    table.setId(rs.getLong("tb_id"));
                    table.setDbId(rs.getLong("tb_db_id"));
                    table.setPrjId(rs.getLong("tb_prj_id"));
                    table.setMcId(rs.getLong("tb_mc_id"));
                    table.setExtends(rs.getString("tb_extends"));
                    table.setName(rs.getString("tb_name").toUpperCase());
                    table.setTitle(rs.getString("tb_title"));
                    table.setAbbr(rs.getString("tb_abbr"));
                    table.setType(rs.getInt("tb_type"));
                    table.setNeedCache(rs.getInt("tb_need_cache") == 1);
                    table.setCreateUid(rs.getLong("tb_create_uid"));
                    table.setUpdateUid(rs.getLong("tb_update_uid"));
                    table.setCreateAt(rs.getLong("tb_create_at"));
                    table.setUpdateAt(rs.getLong("tb_update_at"));
                    table.setContent(rs.getString("tb_content"));
                }
                return list;
            }
        });
    }

    public final ModelTable getByName(String key) {
        return getByKey(mk, key.toUpperCase());
    }

    public final Set<ModelTable> getDbTables(long dbId) {
        return getListByKey(md, String.valueOf(dbId));
    }

    public final Set<ModelTable> getTablesByMc(long mcId) {
        return getListByKey(mc, String.valueOf(mcId));
    }

    public final List<ModelTable> getTablesByMc(long mcId, Comparator<ModelTable> comparator) {
        Set<ModelTable> set = getListByKey(mc, String.valueOf(mcId));
        if (set == null || set.isEmpty()) return null;
        List<ModelTable> list = new ArrayList<>(set);
        list.sort(comparator);
        return list;
    }

    public final String getTableName(long id) {
        ModelTable bean = get(id);
        return bean == null ? String.valueOf(id): bean.getTitle();
    }

    //根据外键
    public final Set<ModelTable> getByLink(long tableId) {
        return getListByKey(mk_link, String.valueOf(tableId));
    }
}
