package com.smppw.common.cache;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.smppw.constants.Consts;
import com.smppw.constants.DateConst;
import com.smppw.constants.IndexConst;
import com.smppw.constants.SearchConst;
import com.smppw.common.pojo.IndexesTradeDateDo;
import com.smppw.common.pojo.ValueLabelDo;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;

import java.util.List;
import java.util.Map;

/**
 * @author lizhuang
 * @Title: ${file_name}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2021/10/23 14:05
 */
public class CaffeineLocalCache extends BasicLocalCache {

    /******************************************************************************************************************************/
    // 添加机构基本信息列到缓存中
    private static final Cache<String, List<String>> COMPANY_BASE_INFO_COLUMNS = Caffeine.newBuilder().maximumSize(16384).build();
    // 添加机构指标列到缓存中
    private static final Cache<String, List<String>> COMPANY_INDICATOR_COLUMNS = Caffeine.newBuilder().maximumSize(16384).build();
    // 添加经理基本信息列到缓存中
    private static final Cache<String, List<String>> MANAGER_BASE_INFO_COLUMNS = Caffeine.newBuilder().maximumSize(16384).build();
    // 添加经理指标列到缓存中
    private static final Cache<String, List<String>> MANAGER_INDICATOR_COLUMNS = Caffeine.newBuilder().maximumSize(16384).build();
    /**
     * 缓存所有非交易日 日期
     */
    private static Cache<String, String> NON_TRADING_DAY = Caffeine.newBuilder().maximumSize(16384).build();
    /**
     * 缓存所有日期对应的年周
     */
    private static Cache<String, String> DATE_YEAR_WEEK = Caffeine.newBuilder().maximumSize(16384).build();
    /**
     * 缓存所有年周的最后交易日
     */
    private static Cache<String, String> YEAR_WEEK_LAST_TRADE_DATE = Caffeine.newBuilder().maximumSize(16384).build();
    /**
     * 缓存所有日期对应的年月
     */
    private static Cache<String, String> DATE_YEAR_MONTH = Caffeine.newBuilder().maximumSize(16384).build();
    /**
     * 缓存所有的三方指数ID
     */
    private static Cache<String, List<String>> THIRD_INDEXES = Caffeine.newBuilder().maximumSize(16384).build();
    private static Cache<String, String> DATE_MONTH_WEEK = Caffeine.newBuilder().maximumSize(16384).build();
    /**
     * 缓存所有年月的最后交易日
     */
    private static Cache<String, String> YEAR_MONTH_LAST_TRADE_DATE = Caffeine.newBuilder().maximumSize(8192).build();
    /**
     * 交易日  indexes_trade_date 指数和交易日一对多
     */
    private static Cache<String, List<IndexesTradeDateDo>> LIST_INFO_TREND_DATE = Caffeine.newBuilder().maximumSize(1).build();
    /**
     * 缓存所有的无风险ID
     */
    private static Cache<String, List<String>> RISKOFFREEIDS = Caffeine.newBuilder().maximumSize(16384).build();
    /**
     * 缓存 基金研究 所有的 key对应的配置项
     */
    private static Cache<String, List<ValueLabelDo>> INDICATOR_SCREENING_CONFIG = Caffeine.newBuilder().maximumSize(16384).build();
    private static Cache<String, List<String>> YEAR_INDICATOR = Caffeine.newBuilder().maximumSize(16384).build();

    /**
     * 获取某一天前最接近的一个交易日日期
     *
     * @param date
     * @return
     */
    public static String getClosestTradingDay(DateTime date) {
        String result = date.toString(Consts.DEFAULT_DATE_PATTERN);
        for (int i = 1; i <= 30; i++) {
            String tradingDate = date.minusDays(i).toString(Consts.DEFAULT_DATE_PATTERN);
            String value = NON_TRADING_DAY.getIfPresent(tradingDate);
            if (StringUtils.isEmpty(value)) {
                result = tradingDate;
                break;
            }
        }
        return result;
    }

    /**
     * 添加非交易日日期
     */
    public static void addNonTradingDay(List<String> dates) {
        for (String date : dates) {
            NON_TRADING_DAY.put(date, date);
        }
    }

    /**
     * 判断某一天是否为交易日
     *
     * @param date
     * @return
     */
    public static boolean getIsTradingDay(String date) {
        if (StringUtils.isEmpty(date)) {
            return false;
        }
        String value = NON_TRADING_DAY.getIfPresent(date);
        return StringUtils.isEmpty(value);
    }

    public static void cleanDateYearWeek() {
        DATE_YEAR_WEEK.invalidateAll();
    }

    public static String getYearWeekByDate(String date) {
        return DATE_YEAR_WEEK.getIfPresent(date);
    }

    public static void addDateYearWeek(List<IndexesTradeDateDo> indexesTradeDateDoList) {
        for (IndexesTradeDateDo indexesTradeDateDo : indexesTradeDateDoList) {
            DATE_YEAR_WEEK.put(indexesTradeDateDo.getTradeDate(), indexesTradeDateDo.getYearWeek());
        }
    }

    public static void cleanYearWeekLastTradeDate() {
        YEAR_WEEK_LAST_TRADE_DATE.invalidateAll();
    }

    public static String getLastTradeDateByYearWeek(String yearWeek) {
        return YEAR_WEEK_LAST_TRADE_DATE.getIfPresent(yearWeek);
    }

    public static void addYearWeekLastTradeDate(List<IndexesTradeDateDo> indexesTradeDateDoList) {
        for (IndexesTradeDateDo indexesTradeDateDo : indexesTradeDateDoList) {
            YEAR_WEEK_LAST_TRADE_DATE.put(indexesTradeDateDo.getYearWeek(), indexesTradeDateDo.getTradeDate());
        }
    }

    public static void cleanDateYearMonth() {
        DATE_YEAR_MONTH.invalidateAll();
    }

    public static void addDateYearMonth(List<IndexesTradeDateDo> indexesTradeDateDoList) {
        for (IndexesTradeDateDo indexesTradeDateDo : indexesTradeDateDoList) {
            DATE_YEAR_MONTH.put(indexesTradeDateDo.getTradeDate(), indexesTradeDateDo.getYearmonth());
        }
    }

    public static void cleanThirdIndexes() {
        THIRD_INDEXES.invalidateAll();
    }

    public static List<String> getThirdIndexes() {
        return THIRD_INDEXES.getIfPresent(IndexConst.THIRD_INDEXES_CAFFEINE_KEY);
    }

    public static void addThirdIndexes(List<String> indexIdList) {
        THIRD_INDEXES.put(IndexConst.THIRD_INDEXES_CAFFEINE_KEY, indexIdList);
    }

    public static void cleanDateMonthWeek() {
        DATE_MONTH_WEEK.invalidateAll();
    }

    public static void addDateMonthWeek(Map<String, String> dateCateMap) {
        for (Map.Entry<String, String> dateCateMapEntry : dateCateMap.entrySet()) {
            DATE_MONTH_WEEK.put(dateCateMapEntry.getKey(), dateCateMapEntry.getValue());
        }
    }

    public static String getDateMonthWeek(String date) {
        return DATE_MONTH_WEEK.getIfPresent(date);
    }

    public static void addYearMonthLastTradeDate(List<IndexesTradeDateDo> indexesTradeDateDoList) {
        for (IndexesTradeDateDo indexesTradeDateDo : indexesTradeDateDoList) {
            YEAR_MONTH_LAST_TRADE_DATE.put(indexesTradeDateDo.getYearmonth(), indexesTradeDateDo.getTradeDate());
        }
    }

    public static void cleanYearMonthLastTradeDate() {
        YEAR_MONTH_LAST_TRADE_DATE.invalidateAll();
    }

    public static void addListInfoTrendDate(List<IndexesTradeDateDo> indexesTradeDateDoList) {
        LIST_INFO_TREND_DATE.put(DateConst.TREND_DATE, indexesTradeDateDoList);
    }

    public static List<IndexesTradeDateDo> getListInfoTrendDate() {
        return LIST_INFO_TREND_DATE.getIfPresent(DateConst.TREND_DATE);
    }

    public static void cleanListInfoTrendDate() {
        LIST_INFO_TREND_DATE.invalidateAll();
    }

    public static void cleanRiskOfFreeId() {
        RISKOFFREEIDS.invalidateAll();
    }

    public static List<String> getRiskOfFreeId() {
        return RISKOFFREEIDS.getIfPresent(IndexConst.RISKOFFREE_CAFFEINE_KEY);
    }

    public static void addRiskOfFreeId(List<String> indexIdList) {
        RISKOFFREEIDS.put(IndexConst.RISKOFFREE_CAFFEINE_KEY, indexIdList);
    }

    public static void addIndicatorScreeningConfig(Map<String, List<ValueLabelDo>> valueLabelMap) {
        INDICATOR_SCREENING_CONFIG.putAll(valueLabelMap);
    }

    public static Map<String, List<ValueLabelDo>> getIndicatorScreeningConfig() {
        return INDICATOR_SCREENING_CONFIG.asMap();
    }

    public static void addYearFundIndicator(List<String> indicators) {
        YEAR_INDICATOR.put(SearchConst.FUND_YEAR_INDICATOR, indicators);
    }

    public static List<String> getYearFundIndicator() {
        return YEAR_INDICATOR.getIfPresent(SearchConst.FUND_YEAR_INDICATOR);
    }

    public static void addCompanyBaseInfoColumns(List<String> indicators) {
        COMPANY_BASE_INFO_COLUMNS.put(SearchConst.COMPANY_BASE_INFO_COLUMNS, indicators);
    }

    public static List<String> getCompanyBaseInfoColumns() {
        return COMPANY_BASE_INFO_COLUMNS.getIfPresent(SearchConst.COMPANY_BASE_INFO_COLUMNS);
    }

    public static void addCompanyIndicatorColumns(List<String> indicators) {
        COMPANY_INDICATOR_COLUMNS.put(SearchConst.COMPANY_INDICATOR_COLUMNS, indicators);
    }

    public static List<String> getCompanyIndicatorColumns() {
        return COMPANY_INDICATOR_COLUMNS.getIfPresent(SearchConst.COMPANY_INDICATOR_COLUMNS);
    }

    public static void addManagerBaseInfoColumns(List<String> indicators) {
        MANAGER_BASE_INFO_COLUMNS.put(SearchConst.MANAGER_BASE_INFO_COLUMNS, indicators);
    }

    public static List<String> getManagerBaseInfoColumns() {
        return MANAGER_BASE_INFO_COLUMNS.getIfPresent(SearchConst.MANAGER_BASE_INFO_COLUMNS);
    }

    public static void addManagerIndicatorColumns(List<String> indicators) {
        MANAGER_INDICATOR_COLUMNS.put(SearchConst.MANAGER_INDICATOR_COLUMNS, indicators);
    }

    public static List<String> getManagerIndicatorColumns() {
        return MANAGER_INDICATOR_COLUMNS.getIfPresent(SearchConst.MANAGER_INDICATOR_COLUMNS);
    }

    /******************************************************************************************************************************/
}
