package com.yihu.hos.tenant.service;

import com.yihu.ehr.dbhelper.jdbc.DBHelper;
import com.yihu.hos.common.constants.ContextAttributes;
import com.yihu.hos.config.MongoConfig;
import com.yihu.hos.core.log.Logger;
import com.yihu.hos.core.log.LoggerFactory;
import com.yihu.hos.services.ServiceMycatEventService;
import com.yihu.hos.tenant.dao.TenantDao;
import com.yihu.hos.tenant.model.DBInfoModel;
import com.yihu.hos.tenant.model.TenantModel;
import com.yihu.hos.web.framework.constant.MycatConstant;
import com.yihu.hos.web.framework.constant.SqlConstants;
import com.yihu.hos.web.framework.model.Result;
import com.yihu.hos.web.framework.model.bo.ServiceMycat;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @author HZY
 * @vsrsion 1.0
 * Created at 2016/12/2.
 */
@Service("TenantService")
public class TenantService {

    public static final String BEAN_ID = "TenantService";
    static private final Logger logger = LoggerFactory.getLogger(TenantService.class);

    @Autowired
    private TenantDao tenantDao;

    @Autowired
    private MongoConfig mongoConfig;

    @Value("${spring.data.mongodb.gridFsDatabase}")
    private String dbName;

    @Value("${hos.mysql.filePath}")
    private String sqlFilePath;

    @Autowired
    private DBInfoService dbInfoService;

    @Autowired
    private MySqlImportAndExport mySqlImportAndExport;

    @Autowired
    private ServiceMycatEventService serviceMycatEventService;


    public TenantModel findTenantByName(String name) throws Exception {
        List<TenantModel> list = tenantDao.getTenantList(name);
        if (list != null && !list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    public Result getTenantList(Map<String, Object> params) throws Exception {
        return tenantDao.getTenantList(params);
    }

    public TenantModel getTenantById(Long id) throws Exception {
        return tenantDao.getEntity(TenantModel.class, id);
    }

//    @Transactional(rollbackFor={RuntimeException.class, Exception.class})
    public Result addTenant(TenantModel obj) {
        String code = UUID.randomUUID().toString();
        obj.setCode(code);
        obj.setCreated(new Date());
        obj.setCreatedUnix(0);
        obj.setUpdated(new Date());
        obj.setUpdatedUnix(0);
        String errorMessage = null;
        try {
            // 建库建表操作
            DBInfoModel dbInfo = dbInfoService.getDBInfoById(obj.getDataSourceId());
            DBInfoModel db = new DBInfoModel();
            db.setUserName(dbInfo.getUserName());
            db.setPassword(dbInfo.getPassword());
            db.setHost(dbInfo.getHost());
            db.setPort(dbInfo.getPort());
            db.setDbName(MycatConstant.DATA_BASE + obj.getSchema());//新建的数据库命名规则为"db_"+ schema
            //建库，建表，数据复制操作
            errorMessage = mySqlImportAndExport.importSql(db, sqlFilePath);
            if (errorMessage ==null){
                //TODO  mycat操作消息发送；使用zbus；tenant: "mycat"+ IP
                ServiceMycat serrviceMycat = new ServiceMycat();
                serrviceMycat.setSchema(obj.getSchema());
                serrviceMycat.setTenant(MycatConstant.ZBUS_MQ+db.getHost());
                serrviceMycat.setLoginName(obj.getLoginName());
                serrviceMycat.setPassword(obj.getPassword());
                serviceMycatEventService.executeMycatConfig(serrviceMycat, MycatConstant.ZBUS_MQ + dbInfo.getHost());
                tenantDao.saveEntity(obj);
                return Result.success("保存成功");
            }else {
                return Result.error("建库建表操作失败,异常信息\r\n" + errorMessage);
            }

        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.error("保存租户信息失败，异常信息\n" + errorMessage);
    }

    @Transactional
    public Result updateTenant(TenantModel obj) throws Exception {
        TenantModel tenant = tenantDao.getEntity(TenantModel.class, obj.getId());
        tenant.setName(obj.getName());
        tenant.setLoginName(obj.getLoginName());
        tenant.setSchema(obj.getSchema());
        tenant.setPassword(obj.getPassword());
        tenant.setValid(obj.getValid());
        tenant.setUpdated(new Date());
        tenant.setUpdatedUnix(1);
        tenantDao.updateEntity(tenant);
        return Result.success("更新成功");
    }

    @Transactional
    public Result deleteTenant(Long id) throws Exception {
        TenantModel systemApp = tenantDao.getEntity(TenantModel.class, id);
        tenantDao.deleteEntity(systemApp);
        return Result.success("删除成功");
    }

    @Transactional
    public Result createDB(String dbName) throws Exception {
        tenantDao.createDB(dbName);
        return Result.success("新建成功");
    }

    @Transactional
    public Result createDB(DBHelper targetDb,String targetDbName) throws Exception {
        //创建数据库
        String createDb = "CREATE DATABASE IF NOT EXISTS "+targetDbName;
        targetDb.execute(createDb);
        return Result.success("新建成功");
    }


    /**
     *  //TODO 库复制  （测试，可删除）
     * 数据库复制
     * @param targetDbName  目标数据库名称
     * @param targetDbUri   目标数据库连接信息
     * @return
     */
    public Result copyBaseTables(String targetDbName,String targetDbUri) throws Exception {

        String baseDbUri = "jdbc:mysql://172.19.103.57:3306/base_db?user=root&password=xmjkzl";//源数据库连接
        DBHelper originDb = new DBHelper(ContextAttributes.BASE_DB, baseDbUri);
        DBHelper targetDb = new DBHelper(targetDbName, targetDbUri);
        //创建数据库
        createDB(targetDb,targetDbName);
        //查询源数据库所有表名
        String tablesSql = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '"+ ContextAttributes.BASE_DB+"';";
        //创建表
        List<JSONObject> tableNames = originDb.query(tablesSql);
        for (JSONObject jsonObject:tableNames){
            try {
            String tableName = jsonObject.getString(ContextAttributes.TABLE_NAME);
            boolean createTable = targetDb.execute(SqlConstants.CREATE_TABLE + targetDbName+"."+tableName + SqlConstants.LIKE + ContextAttributes.BASE_DB+"."+tableName);
            boolean insertData = targetDb.execute(SqlConstants.INSERT_INTO +  targetDbName+"."+tableName + SqlConstants.SELECT + "*" + SqlConstants.FROM + ContextAttributes.BASE_DB+"."+tableName);
            System.out.println(insertData);
            }catch (Exception e){
                logger.error("执行异常："+e.getMessage());
            }
        }
        //新增表数据
        return Result.success("新建成功");
    }

}
