package com.liquidnet.service.base;

import com.liquidnet.commons.lang.util.JsonUtils;
import org.apache.logging.log4j.util.PropertiesUtil;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;

public class SqlMapping {
    private static final String sqlMapDir = "sqlmap";
    private static Map<String, String> sqlPropertiesMap = new HashMap<>();

    static {
        try {
            URL url = PropertiesUtil.class.getClassLoader().getResource(sqlMapDir);
            if (null != url) {
                File file = new File(url.getFile());
                if (file.exists() && file.isDirectory()) {
                    File[] files = file.listFiles();
                    for (File f : files) {
                        if (f.isFile() && f.getName().endsWith("properties")) {
                            Properties props = PropertiesLoaderUtils.loadAllProperties(sqlMapDir.concat("/") + f.getName());
                            for (Object key : props.keySet()) {
                                String keyStr = key.toString();
                                String value = props.getProperty(keyStr);
                                sqlPropertiesMap.put(keyStr, value);
                            }
                        }
                    }
                }
            }
            System.out.printf("sqlPropertiesMap init count: %s\n", sqlPropertiesMap.size());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

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

        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;
        }

        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 = new LinkedList<>();
        sqls.add(sqlPropertiesMap.get(sqlKey));
        LinkedList<Object[]> paramsList = new LinkedList<>();
        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 = new LinkedList<>();
        sqls.add(sqlPropertiesMap.get(sqlKey));
        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(LinkedList<String> sqls, LinkedList<Object[]> paramsList) {
        LinkedList<Object[]>[] args = new LinkedList[]{paramsList};

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