package com.liquidnet.service.base;

import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.JsonUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

public class SqlMapping {
    static {
        reload();
    }
    private static Properties sqlsProperties;

    public static void reload() {
        sqlsProperties = new Properties();
        InputStream in = ErrorMapping.class.getClassLoader().getResourceAsStream("sqlmap.properties");
        try {
            sqlsProperties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
            System.out.printf("errorsProperties init count: %s\n", sqlsProperties.size());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String get(String sql) {
        return (String) sqlsProperties.get(sql);
    }

    public static class SqlMessage implements Cloneable, Serializable {
        private static final long serialVersionUID = 2208924091512163151L;
        private LinkedList<String> sqls;
        private LinkedList<Object[]>[] args;
        private String redisKey;

        private SqlMessage() {
        }

        public SqlMessage(String json) {
            SqlMapping.SqlMessage sqlMessage = JsonUtils.fromJson(json, SqlMapping.SqlMessage.class);
            this.sqls = sqlMessage.getSqls();
            this.args = sqlMessage.getArgs();
        }

        public LinkedList<String> getSqls() {
            return sqls;
        }

        public void setSqls(LinkedList<String> sqls) {
            this.sqls = sqls;
        }

        public LinkedList<Object[]>[] getArgs() {
            return args;
        }

        public void setArgs(LinkedList<Object[]>[] args) {
            this.args = args;
        }

        public String getRedisKey() {
            return redisKey;
        }

        public void setRedisKey(String redisKey) {
            this.redisKey = redisKey;
        }

        private final static SqlMapping.SqlMessage instance = new SqlMapping.SqlMessage();

        public static SqlMapping.SqlMessage getInstance() {
            try {
                return (SqlMapping.SqlMessage) instance.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return new SqlMapping.SqlMessage();
        }
    }

    /* ---------------------- ---------------------- ---------------------- */

    public static String get(String sqlKey, Object... params) {
        LinkedList<String> sqls = CollectionUtil.linkedListString();
        sqls.add((String) sqlsProperties.get(sqlKey));
        LinkedList<Object[]> paramsList = CollectionUtil.linkedListObjectArr();
        paramsList.add(params);
        LinkedList<Object[]>[] args = new LinkedList[]{paramsList};

        SqlMapping.SqlMessage sqlMessage = SqlMapping.SqlMessage.getInstance();
        sqlMessage.setSqls(sqls);
        sqlMessage.setArgs(args);
        return JsonUtils.toJson(sqlMessage);
    }

    public static String get(String sqlKey, LinkedList<Object[]> paramsList) {
        LinkedList<String> sqls = CollectionUtil.linkedListString();
        sqls.add((String) sqlsProperties.get(sqlKey));
        LinkedList<Object[]>[] args = new LinkedList[]{paramsList};

        SqlMapping.SqlMessage sqlMessage = SqlMapping.SqlMessage.getInstance();
        sqlMessage.setSqls(sqls);
        sqlMessage.setArgs(args);
        return JsonUtils.toJson(sqlMessage);
    }

    @SafeVarargs
    public static String gets(LinkedList<String> sqls, LinkedList<Object[]>... paramsList) {
        SqlMapping.SqlMessage sqlMessage = SqlMapping.SqlMessage.getInstance();
        sqlMessage.setSqls(sqls);
        sqlMessage.setArgs(paramsList);
        return JsonUtils.toJson(sqlMessage);
    }

    public static String getSqlRedis(String redisKey) {
        SqlMapping.SqlMessage sqlMessage = SqlMapping.SqlMessage.getInstance();
        sqlMessage.setRedisKey(redisKey);
        return JsonUtils.toJson(sqlMessage);
    }
}
