package com.sdtool.common.api;

import com.sdtool.common.base.BaseService;
import com.dySweetFishPlugin.redis.RedisService;
import com.sweetfish.util.AnyValue;
import com.sweetfish.util.AutoLoad;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Priority;
import javax.annotation.Resource;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by jlutt on 2018-12-06.
 *
 * @author jlutt
 */
//@Local
@AutoLoad(false)
@Priority(8000)
public class NoSqlKeysService extends BaseService {

    @Resource(name = "APP_HOME")
    String homePath;

    @Resource
    RedisService redisService;

    private String lockOrderScriptHash;

    private final ConcurrentHashMap<String, String> container = new ConcurrentHashMap<>();

    @Override
    public void init(AnyValue config) {
        String dfloads = config.getValue("load");
        if (dfloads != null) {
            for (String dfload : dfloads.split(";")) {
                if (dfload.trim().isEmpty()) continue;
                dfload = dfload.trim().replace("${APP_HOME}", homePath).replace('\\', '/');
                final File df = (dfload.indexOf('/') < 0) ? new File(homePath, "conf/" + dfload) : new File(dfload);
                if (df.isFile()) {
                    try {
                        Properties ps = new Properties();
                        InputStream in = new FileInputStream(df);
                        ps.load(new InputStreamReader(in, StandardCharsets.UTF_8));
                        in.close();
                        ps.forEach((x, y) ->
                                container.putIfAbsent((String) x, (String) y)
                        );
                    } catch (IOException e) {
                        logger.error(e.getMessage(), e);
                    }
                }
            }
        }
    }

    @Override
    public void start(AnyValue config) {
        Path path = Paths.get(homePath + File.separator + "conf" + File.separator + "redisscript" + File.separator + "lock_order.lua");
        this.lockOrderScriptHash = redisService.scriptLoad(readUTF8File(path, false));
    }

    @Override
    public void destroy(AnyValue config) {

    }

    /**
     * 获取redis key
     * 查找RedisKey中在rediskeys.properties对应的value
     *
     * @param key 键值
     * @return 值
     */
    public String getRedisKey(String key) {
        return container.getOrDefault(key, "");
    }

    /**
     * 获取redis key
     *
     * @param key          RedisKey中在rediskeys.properties对应的key
     * @param supplierCode 工厂key
     * @return
     */
    public String getRedisKey(String key, long supplierCode) {
        return getRedisKey(key, supplierCode, false);
    }

    /**
     * 获取redis key
     *
     * @param key          RedisKey中在rediskeys.properties对应的key
     * @param supplierCode 工厂key
     * @param addColon     是否添加分段符:
     * @return
     */
    public String getRedisKey(String key, long supplierCode, boolean addColon) {
        String tmp = container.getOrDefault(key, "");
        if (StringUtils.isEmpty(tmp)) {
            logger.info("有键值未配置：" + key);
        }
        if (addColon) {
            return tmp + ":" + supplierCode + ":";
        } else {
            return tmp + ":" + supplierCode;
        }
    }

    public String getESKey(String key) {
        String tmp = container.getOrDefault(key, "");
        if (StringUtils.isEmpty(tmp)) {
            logger.info("有键值未配置：" + key);
        }
        return tmp;
    }

    public String getESKey(String key, long supplierCode) {
        String tmp = container.getOrDefault(key, "");
        if (StringUtils.isEmpty(tmp)) {
            logger.info("有键值未配置：" + key);
        }
        return tmp + supplierCode;
    }

    /**
     * 获取文档版本
     *
     * @param key
     * @param idDoc 文档唯一id，字符串兼容其它业务
     * @return
     */
    public long getDocVersion(String key, String idDoc) {
        String version = redisService.hget(key, idDoc);
        if (StringUtils.isBlank(version)) {
            return 0;

        }
        return Long.parseLong(version);
    }

    /**
     * 获取文档版本
     *
     * @param key
     * @param idDoc 文档唯一id，字符串兼容其它业务
     * @return
     */
    public List<String> getBatchDocVersion(String key, List<String> idDoc) {
        return redisService.hmget(key, idDoc.toArray(new String[0]));
    }

    /**
     * 文档版本检查，并增加版本号
     *
     * @param key
     * @param idDoc          文档唯一id，字符串兼容其它业务
     * @param currentVersion 传入版本
     * @return -2脚本执行错误 -1版本冲突 >0 返回+1版本号
     */
    public long checkDocVersion(String key, String idDoc, long currentVersion) {
        String version = (String) (redisService.evalsha(this.lockOrderScriptHash,
                1,
                key,
                idDoc,
                String.valueOf(currentVersion)));

        if (StringUtils.isEmpty(version)) {
            return -2;
        }
        return Long.parseLong(version);
    }
}
