package com.jsc.dsp.utils;

import com.alibaba.fastjson.JSONArray;
import com.jsc.dsp.model.Indeximos;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.*;
import java.util.logging.Logger;


public class DBUtils {

    public static Connection conn = null;

    private static final List<String> floatFields = Arrays.asList("es_doclength", "es_negativeProbability", "es_simrank");

    private static final Logger logger = Logger.getLogger("com.jsc.dsp.utils.DBUtils");

    public static Connection getConnection(String driver, String url, String user, String password) {
        try {
            Class.forName(driver);
            return DriverManager.getConnection(url, user, password);
        } catch (ClassNotFoundException | SQLException e) {
            logger.warning("Cannot get DB connection!");
            logger.warning(e.getMessage());
            return null;
        }
    }

    private static Map<String, Object> getObjectMap(Indeximos object) {
        Map<String, Object> resultMap = new HashMap<>();
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            String fieldName = field.getName();
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            try {
                Method method = object.getClass().getMethod(getter);
                Object fieldValue = method.invoke(object);
                resultMap.put(fieldName, fieldValue);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return resultMap;
    }

    public static boolean insertIntoDB(String driver, String url, String user, String password, List<Indeximos> objectList) {
        if (conn == null) {
            conn = getConnection(driver, url, user, password);
        }
        if (conn != null) {
            try {
                PreparedStatement pres = null;
                for (Indeximos object : objectList) {
                    Map<String, Object> objectMap = getObjectMap(object);
                    Object[] keyObjects = objectMap.keySet().toArray();
                    List<String> keys = new ArrayList<>();
                    List<String> values = new ArrayList<>();
                    for (Object ko : keyObjects) {
                        String key = ko.toString();
                        keys.add(key);
                        Object value = objectMap.get(key);
                        if (floatFields.contains(key)) {
                            values.add(value.toString());
                        } else {
                            if (value != null && value.toString().length() > 0) {
                                values.add("'" + value.toString().replace("'", "\\'") + "'");
                            } else {
                                values.add("null");
                            }
                        }
                    }
                    String sqlInsert = "REPLACE INTO indeximos(" + String.join(", ", keys) + ") VALUES("
                            + String.join(", ", values) + ")";
                    pres = conn.prepareStatement(sqlInsert);
                    pres.addBatch();
                }
                if (pres != null) {
                    pres.executeBatch();
                    pres.close();
                }
                return true;
            } catch (SQLException e) {
                logger.warning("Fail to insert data to Database");
                logger.warning(e.getMessage());
                conn = getConnection(driver, url, user, password);
                return false;
            }
        } else {
            return false;
        }
    }


    public static boolean hasField(Class<?> clazz, String fieldName) {
        try {
            clazz.getDeclaredField(fieldName);
            return true;
        } catch (NoSuchFieldException e) {
            return false;
        }
    }

    public static String getFieldType(Class<?> clazz, String fieldName) {
        try {
            Field field = clazz.getDeclaredField(fieldName);
            return field.getType().getName();
        } catch (NoSuchFieldException e) {
            return "";
        }
    }

    public static void main(String[] args) {
        List<Indeximos> objectList = JSONArray.parseArray(FileUtils.readContentFromFile(
                "D:/data/local-storage/indeximos_1700030748332.json"), Indeximos.class);
        insertIntoDB(
                "com.mysql.cj.jdbc.Driver",
                "jdbc:mysql://8.130.95.27:28089/dsp",
                "root",
                "passok123A",
                objectList);
    }

}
