package com.izouma.awesomeadmin.service.impl;

import com.izouma.awesomeadmin.constant.AppConstant;
import com.izouma.awesomeadmin.dao.CommonQueryMapper;
import com.izouma.awesomeadmin.dao.CommonQuerySqlServerMapper;
import com.izouma.awesomeadmin.datasource.DataSource;
import com.izouma.awesomeadmin.dto.Page;
import com.izouma.awesomeadmin.model.CommonQuery;
import com.izouma.awesomeadmin.service.CommonQueryService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * service接口实现类
 */
@Service
public class CommonQueryServiceImpl implements CommonQueryService {

    private static Logger logger = Logger.getLogger(CommonQueryServiceImpl.class);

    @Autowired
    private CommonQueryMapper commonQueryMapper;

    @Autowired
    private CommonQuerySqlServerMapper cmmonQuerySqlServerMapper;

    @Override
    public List<Map> getTableListByPage(Page page, CommonQuery record) {

        logger.info("getTableListByPage");
        try {
            changeDataSource(record.getDataSourceCode(), record.getDatabasetype());

            Map<String, Object> parameter = new HashMap<String, Object>();
            parameter.put("record", record);
            parameter.put(AppConstant.PAGE, page);

            if ("Mysql".equals(record.getDatabasetype())) {
                return commonQueryMapper.getTableListByPage(parameter);
            } else if ("SqlServer".equals(record.getDatabasetype())) {
                return cmmonQuerySqlServerMapper.getTableListByPage(parameter);
            }


        } catch (Exception e) {
            logger.error("getTableListByPage", e);
        }

        return null;
    }

    @Override
    public List<Map> getTableListAll(CommonQuery record) {

        logger.info("getTableListAll");
        try {

            changeDataSource(record.getDataSourceCode(), record.getDatabasetype());

            if ("Mysql".equals(record.getDatabasetype())) {

                return commonQueryMapper.getTableListAll(record);
            } else if ("SqlServer".equals(record.getDatabasetype())) {
                return cmmonQuerySqlServerMapper.getTableListAll(record);
            }


        } catch (Exception e) {
            logger.error("getTableListAll", e);
        }

        return null;
    }

    @Override
    public Map selectByPrimaryKey(CommonQuery record) {

        logger.info("selectByPrimaryKey");
        try {

            changeDataSource(record.getDataSourceCode(), record.getDatabasetype());

            if ("Mysql".equals(record.getDatabasetype())) {
                return commonQueryMapper.selectByPrimaryKey(record);
            } else if ("SqlServer".equals(record.getDatabasetype())) {
                return cmmonQuerySqlServerMapper.selectByPrimaryKey(record);
            }


        } catch (Exception e) {
            logger.error("selectByPrimaryKey", e);
        }

        return null;
    }

    @Override
    public boolean create(Map<String, Object> parameter) {

        logger.info("create");
        try {
            changeDataSource(parameter.get("dataSourceCode").toString(), parameter.get("databasetype").toString());

            int updates = 0;
            if ("Mysql".equals(parameter.get("databasetype").toString())) {
                updates = commonQueryMapper.insertSelective(parameter);
            } else if ("SqlServer".equals(parameter.get("databasetype").toString())) {
                updates = cmmonQuerySqlServerMapper.insertSelective(parameter);
            }


            if (updates > 0) {
                return true;
            }
        } catch (Exception e) {
            logger.error("create", e);
        }

        return false;
    }


    @Override
    public boolean update(Map<String, Object> parameter) {

        logger.info("update");
        try {
            changeDataSource(parameter.get("dataSourceCode").toString(), parameter.get("databasetype").toString());
            int updates = 0;
            if ("Mysql".equals(parameter.get("databasetype").toString())) {
                updates = commonQueryMapper.updateByPrimaryKeySelective(parameter);
            } else if ("SqlServer".equals(parameter.get("databasetype").toString())) {
                updates = cmmonQuerySqlServerMapper.updateByPrimaryKeySelective(parameter);
            }


            if (updates > 0) {
                return true;
            }
        } catch (Exception e) {
            logger.error("update", e);
        }

        return false;
    }


    @Override
    public boolean delete(CommonQuery record) {


        logger.info("delete");
        try {
            changeDataSource(record.getDataSourceCode(), record.getDatabasetype());
            int updates = 0;
            if ("Mysql".equals(record.getDatabasetype())) {
                updates = commonQueryMapper.delete(record);
            } else if ("SqlServer".equals(record.getDatabasetype())) {
                updates = cmmonQuerySqlServerMapper.delete(record);
            }


            if (updates > 0) {
                return true;
            }
        } catch (Exception e) {
            logger.error("delete", e);
        }

        return false;
    }

    /**
     * 切换数据库注解
     *
     * @param dateSourceCode
     * @param databaseType
     */
    public void changeDataSource(String dateSourceCode, String databaseType) {

        try {


            //获取注解实例
            DataSource foo = CommonQueryMapper.class.getAnnotation(DataSource.class);
            if ("SqlServer".equals(databaseType)) {
                foo = CommonQuerySqlServerMapper.class.getAnnotation(DataSource.class);
            }
            //获取注解实例的 value 属性值
            String value = foo.value();
            //打印该值
            logger.info("修改之前的注解值：" + value);

            logger.info("------------以下是修改注解的值------------");

            //获取 foo 这个代理实例所持有的 InvocationHandler
            InvocationHandler invocationHandler = Proxy.getInvocationHandler(foo);
            // 获取 AnnotationInvocationHandler 的 memberValues 字段
            Field declaredField = invocationHandler.getClass().getDeclaredField("memberValues");
            // 因为这个字段事 private final 修饰，所以要打开权限
            declaredField.setAccessible(true);
            // 获取 memberValues
            Map memberValues = (Map) declaredField.get(invocationHandler);
            // 修改 value 属性值
            memberValues.put("value", dateSourceCode);
            // 获取 foo 的 value 属性值
            String newValue = foo.value();
            logger.info("修改之后的注解值：" + newValue);
        } catch (Exception e) {
            logger.error("切换数据库失败", e);
        }
    }
}

