package com.product.data.sync.util;

import com.beust.jcommander.internal.Lists;
import com.google.common.collect.Maps;
import com.product.common.collect.ListUtils;
import com.product.core.dao.BaseDao;
import com.product.core.entity.FieldSetEntity;
import com.product.core.exception.BaseException;
import com.product.core.service.support.AbstractBaseService;
import com.product.util.BaseUtil;
import com.product.util.CallBack;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.InvocationTargetException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class DataAddSynchronization extends AbstractBaseService implements Runnable {
    @Autowired
    public ExceptionLog exceptionLog;

    public ExceptionLog getExceptionLog() {
        return exceptionLog;
    }

    public void setExceptionLog(ExceptionLog exceptionLog) {
        this.exceptionLog = exceptionLog;
    }

    @Autowired
    public BaseDao baseDao;

    @Override
    public BaseDao getBaseDao() {
        return baseDao;
    }

    @Override
    public void setBaseDao(BaseDao baseDao) {
        this.baseDao = baseDao;
    }

    private ResultSet resultSet;
    private Map<String, String> map;
    private Map<String, String> syncMap;
    private Map<String, String> sileMap;
    private CallBack callBack;

    public DataAddSynchronization(ResultSet resultSet, Map<String, String> map, Map<String, String> sileMap, Map<String, String> syncMap) {
        this.resultSet = resultSet;
        this.map = map;
        this.syncMap = syncMap;
        this.sileMap = sileMap;
    }

    public void setCallBack(CallBack callBack) {
        this.callBack = callBack;
    }

    @Override
    public void run() {
        //绯荤粺琛ㄥ悕
        String tableName = map.get("tableName");
        //鏃ュ織uuid
        String logUuid = map.get("logUuid");
        //浜嬩欢鍓嶈皟鐢�
        String savePreEvent = map.get("savePreEvent");
        //浜嬩欢鍚庤皟鐢�
        String postSaveEvent = map.get("postSaveEvent");
        //杩唬鏁伴噺
        Integer resultRow = 0;
        //鏂板鏁伴噺
        Integer addNum = 0;
        List<String> addDataRecord = new ArrayList<>();
        //閿欒鏁伴噺
        Integer errorNum = 0;
        List<String> list = ListUtils.newArrayList();
        while (true) {
            try {
                if (!resultSet.next()) break;
            } catch (SQLException e) {
                exceptionLog.upExceptionLog(logUuid, e);
                break;
            }
            try {
                FieldSetEntity fieldSet = new FieldSetEntity();
                fieldSet.setTableName(tableName);
                resultRow++;
                StringBuffer condition = new StringBuffer();
                for (String key : syncMap.keySet()) {
                    fieldSet.setValue(syncMap.get(key), resultSet.getString(key));
                }
                list.clear();
                for (String key : sileMap.keySet()) {
                    String value = resultSet.getString(key);
                    String fieldName = sileMap.get(key);
                    fieldSet.setValue(fieldName, value);
                    condition.append(fieldName).append(" = ? AND ");
                    list.add(value);
                }
                //璋冪敤淇濆瓨鍓嶆柟娉�
                if (!BaseUtil.strIsNull(savePreEvent) && savePreEvent.indexOf(".") != -1) {
                    DataManipulationUtils.codeCalls(savePreEvent, fieldSet);
                }
                String term = condition.substring(0, condition.length() - 4);
                FieldSetEntity fieldSetEntityByFilter = baseDao.getFieldSetEntityByFilter(tableName, term, list.toArray(new String[]{}), false);
                //濡傛灉鏈煡鍒版暟鎹氨鏂板
                if (fieldSetEntityByFilter == null) {
                    baseDao.add(fieldSet);
                    addNum++;
                } else {
                    errorNum++;
                }
                //璋冪敤淇濆瓨鍚庢柟娉�
                if (!BaseUtil.strIsNull(postSaveEvent) && postSaveEvent.indexOf(".") != -1) {
                    DataManipulationUtils.codeCalls(postSaveEvent, fieldSet);
                }
            } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | BaseException | SQLException e) {
                errorNum++;
                exceptionLog.addSubExceptionLog(logUuid, list, e);
                continue;
            }
        }
        Map<String, Object> map = Maps.newHashMap();
        //杩唬鏁伴噺
        map.put("resultRow", (resultRow));
        //鏂板鏁伴噺
        map.put("addNum", (addNum));
        //閿欒鏁伴噺
        map.put("errorNum", (errorNum));
        map.put("changeDataKeys", Lists.newArrayList(addDataRecord));
        //鍥炶皟鍑芥暟
        if (this.callBack != null) {
            callBack.method(map);
        }
    }
}