package com.elab.core.spring.method;

import com.elab.core.spring.base.EntityOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * 默认的sql实现
 *
 * @author Liukx
 * @create 2018-01-04 19:05
 * @email liukx@elab-plus.com
 **/
public class DefaultSQLBuilderSupport implements ISQLBuliderSupport {

    private Logger log = LoggerFactory.getLogger(DefaultSQLBuilderSupport.class);

    public final String insertMethodName = "insert";
    public final String updateMethodName = "updateById";
    public final String deleteMethodName = "delete";
    public final String selectByObjectMethodName = "selectByObject";
    public final String selectByListMethodName = "selectByList";
    public final String findMethodName = "find";
    public final String selectByPage = "selectByPage";
    public final String selectById = "selectById";
    public final String selectByMapper = "selectByMapper";
    public final String batchInsertByObject = "batchInsertByObject";
    public final String batchInsertByMap = "batchInsertByMap";
    public final String batchUpdateByObject = "batchUpdateByObject";
    public final String batchUpdateByMap = "batchUpdateByMap";
    public final String selectByObjectToCount = "selectByObjectToCount";


    /**
     * 创建sql语句流程
     *
     * @param entityOperation
     * @param method
     * @return
     */
    @Override
    public String doCreateSQL(EntityOperation entityOperation, Method method) {
        String name = method.getName();
        String sql = "";
        if (insertMethodName.equals(name) || batchInsertByObject.equals(name) || batchInsertByMap.equals(name)) {
            sql = insertSql(entityOperation);
        } else if (updateMethodName.equals(name) || batchUpdateByObject.equals(name) || batchUpdateByMap.equals(name)) {
            sql = updateSql(entityOperation);
        } else if (deleteMethodName.equals(name)) {
            sql = deleteSql(entityOperation);
        } else if (selectByObjectMethodName.equals(name) || selectByListMethodName.equals(name) || selectByPage.equals(name) || selectByMapper.equals(name)) {
            sql = selectSql(entityOperation);
        } else if (selectById.equals(name)) {
            sql = selectByIdSql(entityOperation);
        } else if (selectByObjectToCount.equals(name)) {
            sql = getSelectByObjectToCount(entityOperation);
        }
        // 上层给做掉的了
        else if (findMethodName.equals(name)) {
//            sql = findSql(entityOperation,method);
        }
        log.debug(" 默认创建的SQL : " + sql);
        return sql;
    }

    /**
     * 根据主键创建一个对象
     *
     * @param entityOperation
     * @return
     */
    private String selectByIdSql(EntityOperation entityOperation) {
        String allColumn = entityOperation.allColumn;
        String tableName = entityOperation.tableName;
        String id = entityOperation.pkField.getName();
        StringBuffer sb = new StringBuffer();
        // 这里默认会将主键放在第一位
        sb.append(" select " + allColumn + " from " + tableName + " where " + id + " = :id ");
        return sb.toString();
    }

    /**
     * 创建删除语句流程
     *
     * @param entityOperation
     * @return
     */
    private String deleteSql(EntityOperation entityOperation) {
//        String allColumn = entityOperation.allColumn;
        String tableName = entityOperation.tableName;
        String id = entityOperation.pkField.getName();
        Map<String, String> allProperty = entityOperation.allProperty;
        allProperty.remove(id);
        StringBuffer sb = new StringBuffer();
        sb.append("delete from " + tableName + " where ");
        sb.append(" " + id + " =:" + id + " and ");
        mappingToString(allProperty, sb, "and", " =:");
        return sb.toString();
    }

    /**
     * 修改sql查询
     *
     * @param entityOperation
     * @return
     */
    private String updateSql(EntityOperation entityOperation) {
//        String allColumn = entityOperation.allColumn;
        String tableName = entityOperation.tableName;
        String id = entityOperation.pkField.getName();
        Map<String, String> allProperty = entityOperation.allProperty;
        StringBuffer sb = new StringBuffer();
        sb.append("update " + tableName + " set ");
        allProperty.remove(id);
        mappingToString(allProperty, sb, ",", " =:");
        sb.append(" where " + id + " =:" + id);
        return sb.toString();
    }

    /**
     * 字段名映射
     *
     * @param allProperty      所有属性
     * @param sb               sql语句
     * @param whereSeparator   条件分割符号
     * @param mappingSeparator 属性分隔符
     */
    private void mappingToString(Map<String, String> allProperty, StringBuffer sb, String whereSeparator, String mappingSeparator) {
        // 遍历map集合
        boolean isNotFirst = false;
        // 不同的操作
        for (Map.Entry<String, String> entry : allProperty.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (isNotFirst) {
                sb.append(" " + whereSeparator + " ");
            }
            isNotFirst = true;
            sb.append(key + " " + mappingSeparator + value);

        }
    }

    /**
     * 添加sql语句特殊化处理
     *
     * @param allProperty
     * @param sb
     * @param whereSeparator
     * @param mappingSeparator
     */
    private void mappingToInsertString(Map<String, String> allProperty, StringBuffer sb, String whereSeparator, String mappingSeparator) {
        // 遍历map集合
        boolean isNotFirst = false;
        // 不同的操作
        for (Map.Entry<String, String> entry : allProperty.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (isNotFirst) {
                sb.append(" " + whereSeparator + " ");
            }
            sb.append(" " + mappingSeparator + value);
            isNotFirst = true;
        }
    }

    /**
     * 添加sql生成
     *
     * @param entityOperation
     * @return
     */
    public String insertSql(EntityOperation entityOperation) {
        String allColumn = entityOperation.allColumn;
        String tableName = entityOperation.tableName;
        Map<String, String> allProperty = entityOperation.allProperty;
        StringBuffer sb = new StringBuffer();
        sb.append(" insert into " + tableName + " (" + allColumn + ") values (");
        mappingToInsertString(allProperty, sb, ",", ":");
        sb.append(" )");
        return sb.toString();
    }

    /**
     * 查询sql生成
     *
     * @param entityOperation
     * @return
     */
    public String selectSql(EntityOperation entityOperation) {
        String allColumn = entityOperation.allColumn;
        String tableName = entityOperation.tableName;
        Map<String, String> allProperty = entityOperation.allProperty;
        String id = entityOperation.pkField.getName();
        StringBuffer sb = new StringBuffer();
        // 这里默认会将主键放在第一位
        sb.append(" select  " + allColumn + " from " + tableName + " where " + id + " =:" + id + " and ");
        mappingToString(allProperty, sb, " and ", "=:");
        return sb.toString();
    }

    public String getSelectByObjectToCount(EntityOperation entityOperation) {
        String allColumn = entityOperation.allColumn;
        String tableName = entityOperation.tableName;
        Map<String, String> allProperty = entityOperation.allProperty;
        String id = entityOperation.pkField.getName();
        StringBuffer sb = new StringBuffer();
        // 这里默认会将主键放在第一位
        sb.append(" select  count(1) from " + tableName + " where " + id + " =:" + id + " and ");
        mappingToString(allProperty, sb, " and ", "=:");
        return sb.toString();
    }

}
