package com.bocloud.ims.service.resource.database;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.database.DatabaseDriver;
import com.bocloud.cmp.entity.enums.CacheMode;
import com.bocloud.cmp.model.database.DbInstanceDbModel;
import com.bocloud.cmp.model.database.DbInstanceModel;
import com.bocloud.cmp.model.database.DbInstanceUserModel;
import com.bocloud.common.encrypt.AESEncrptor;
import com.bocloud.common.encrypt.DESEncrptor;
import com.bocloud.common.encrypt.Encryptor;
import com.bocloud.common.model.*;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.common.utils.ListTool;
import com.bocloud.common.utils.MapTools;
import com.bocloud.ims.entity.enums.RdsInstanceStatus;
import com.bocloud.ims.entity.middleware.*;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.interfaces.resource.database.RdsPublicCloudInstanceService;
import com.bocloud.ims.repository.database.*;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Company: 博云 www.bocloud.com
 * @ClassName: RdsServiceImpl
 * @Description:
 * @author: liuyuanyuan
 */
@Service("rdsPublicCloudInstanceService")
public class RdsPublicCloudInstanceServiceImpl implements RdsPublicCloudInstanceService {

    private static Logger logger = LoggerFactory.getLogger(RdsPublicCloudInstanceServiceImpl.class);
    @Autowired
    private DatabaseDriver databaseDriver;
    @Autowired
    private CloudVendorRepository cloudVendorRepository;
    @Autowired
    private RdsPublicCloudInstanceRepository rdsPublicCloudInstanceRepository;
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    private ResourceEventPublisher resourceEventPublisher;
    @Autowired
    private RdsPublicCLoudFlavorRepository rdsPublicCLoudFlavorRepository;
    @Autowired
    private RdsPublicCloudInstanceParameterGroupRepository rdsPublicCloudInstanceParameterGroupRepository;
    @Autowired
    private RdsUserRepository rdsUserRepository;
    @Autowired
    private RdsDbRepository rdsDbRepository;

    @Override
    public BocloudResult list(Pager pager) {
        GridBean gridBean = null;
        try {
            int page = pager.getPage();
            int rows = pager.getRows();
            List<Param> params = pager.getParams();
            Map<String, String> sorter = pager.getSorter();
            boolean simple = pager.getSimple();

            if (null == params) {
                params = Lists.newArrayList();
            }
            if (null == sorter) {
                sorter = Maps.newHashMap();
            }
            sorter.put("gmtCreate", Common.ONE);
            int total = this.rdsPublicCloudInstanceRepository.count(params);
            if (simple) {
                List<SimpleBean> beans = this.rdsPublicCloudInstanceRepository.list(params, sorter);
                gridBean = new GridBean(1, 1, total, beans);
            } else {
                List<RdsPublicCloudInstance> partitions = this.rdsPublicCloudInstanceRepository.list(page, rows, params,
                        sorter);
                gridBean = GridHelper.getBean(page, rows, total, partitions);
            }
            return new BocloudResult(true, gridBean, "查询成功");
        } catch (Exception e) {
            logger.error("Query dbInstance list fail:", e);
            return new BocloudResult(false, "查询失败");
        }
    }

    @Override
    public BocloudResult detail(Long id) {
        try {
            RdsPublicCloudInstance instance = rdsPublicCloudInstanceRepository.query(id);
//            DbInstanceModel rds = JSONObject.parseObject(JSONObject.parse(String.valueOf(instance)).toString(), DbInstanceModel.class);
//            Long vendorId = rds.getVendorId();
//            CloudVendor vendor = cloudVendorRepository.query(vendorId);
//            if (null == vendor) {
//                logger.info("cloud vendor is not exist!");
//                return new BocloudResult(false, "云平台不存在");
//            }
//            RdsPublicCloudInstance rdsPublicCloudInstance = rdsPublicCloudInstanceRepository.queryByInsId(rds.getInstanceId());
//            converter(rdsPublicCloudInstance);
            return new BocloudResult(true, instance, "查询成功");
        } catch (Exception e) {
            logger.error("Get error message：", e);
            return new BocloudResult(false, "查询失败");
        }
    }

    @Override
    public BocloudResult createUser(Long id, RdsUser rdsUser, RequestContext context) {
        try {
            RdsPublicCloudInstance instance = rdsPublicCloudInstanceRepository.query(id);
            if (null == instance) {
                logger.info("db instance is not exist!");
                return new BocloudResult(false, "rds实例不存在");
            }
            CloudVendor cloudVendor = cloudVendorRepository.query(rdsUser.getVendorId());
            if (null == cloudVendor) {
                logger.info("cloud vendor is not exist!");
                return new BocloudResult(false, "云平台不存在");
            }
            rdsUser.setGmtCreate(new Date());
            rdsUser.setCreatorId(context.getTarget());
            rdsUser.setDeleted(false);
            rdsUser.setStatus(RdsInstanceStatus.Unavailable.name());
            rdsUserRepository.save(rdsUser);
            taskExecutor.execute(() -> {
                String operate = cloudVendor.getType().toLowerCase() + ".rds.user.create";
                String content = "账号创建失败";
                DbInstanceUserModel userModel = new DbInstanceUserModel();
                userModel.setDBInstanceId(instance.getInstanceId());
                userModel.setAccountName(rdsUser.getUsername());
                userModel.setAccountPassword(new AESEncrptor().decrypt(rdsUser.getPassword(), null));
                userModel.setAccountDescription(rdsUser.getRemark());
                userModel.setAccountType(rdsUser.getPermission());
                BocloudResult result = databaseDriver.createAccount(cloudVendor.getUuid(), instance.getRegionId(),
                        userModel);
                if (result.isSuccess()) {
                    content = "账号【" + rdsUser.getUsername() + "】创建成功";
                    DbInstanceUserModel model = (DbInstanceUserModel) result.getData();
                    rdsUser.setUsername(model.getAccountName());
                    rdsUser.setPermission(model.getAccountType());
                    rdsUser.setStatus(model.getAccountStatus());
                    rdsUser.setRemark(model.getAccountDescription());
                    rdsUser.setRdsId(instance.getId());
                    rdsUser.setPrivileges(model.getDatabasePrivileges().toJSONString());
                    rdsUser.setDeleted(false);
                    rdsUserRepository.update(rdsUser);
                } else {
                    content += ":" + result.getMessage();
                    logger.error("创建账号异常：" + content);
                    rdsUserRepository.remove(rdsUser.getId(), context.getTarget());
                }
                resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
                        MapTools.simpleMap(Common.VENDORID, cloudVendor.getId()),
                        OperateResult.OperateCategory.ResourceEvent, context));
            });
            return new BocloudResult(true, "任务已下发，正在执行......");
        } catch (Exception e) {
            logger.error("create rds instance user is error：", e);
            return new BocloudResult(false, "实例用户创建失败 : " + e.getMessage());
        }
    }

    @Override
    public BocloudResult createDb(Long id, RdsDb rdsDb, RequestContext context) {
        try {
            RdsPublicCloudInstance instance = rdsPublicCloudInstanceRepository.query(id);
            if (null == instance) {
                logger.info("db instance is not exist!");
                return new BocloudResult(false, "rds实例不存在");
            }
            CloudVendor cloudVendor = cloudVendorRepository.query(instance.getVendorId());
            if (null == cloudVendor) {
                logger.info("cloud vendor is not exist!");
                return new BocloudResult(false, "云平台不存在");
            }

            DbInstanceDbModel dbModel = new DbInstanceDbModel();
            Long accountId = rdsDb.getAccountId();
            RdsUser rdsUser = null;
            if (null != accountId) {
                rdsUser = rdsUserRepository.query(accountId);
                if (null == rdsUser) {
                    return new BocloudResult<>(false, "账号不存在");
                }
                dbModel.setAccountName(rdsUser.getUsername());
            }
            rdsDb.setGmtCreate(new Date());
            rdsDb.setCreatorId(context.getTarget());
            rdsDb.setVendorId(cloudVendor.getId());
            rdsDb.setDeleted(false);
            rdsDb.setStatus(RdsInstanceStatus.Unavailable.name());
            rdsDbRepository.save(rdsDb);
            final RdsUser newRdsUser = rdsUser;
            taskExecutor.execute(() -> {
                String operate = cloudVendor.getType().toLowerCase() + ".rds.db.create";
                String content = "rds实例数据库创建失败";
                dbModel.setDBInstanceId(instance.getInstanceId());
                dbModel.setDBName(rdsDb.getName());
                dbModel.setCharacterSetName(rdsDb.getCharacterSet());
                dbModel.setDBDescription(rdsDb.getRemark());
                dbModel.setAccountPrivilege(rdsDb.getAccountPrivilege());
                BocloudResult result = databaseDriver.createDatabase(cloudVendor.getUuid(), null, dbModel);
                if (result.isSuccess()) {
                    DbInstanceDbModel model = (DbInstanceDbModel) result.getData();
                    rdsDb.setName(model.getDBName());
                    rdsDb.setStatus(model.getDBStatus());
                    rdsDb.setCharacterSet(model.getCharacterSetName());
                    rdsDb.setRemark(model.getDBDescription());
                    rdsDb.setEngine(model.getEngine());
                    rdsDb.setAccounts(model.getAccounts().toJSONString());
                    rdsDb.setDeleted(false);
                    rdsDb.setRdsId(instance.getId());
                    rdsDbRepository.update(rdsDb);
                    if (null != newRdsUser) {
                        DbInstanceUserModel userModel = model.getUserModel();
                        newRdsUser.setStatus(userModel.getAccountStatus());
                        newRdsUser.setPrivileges(userModel.getDatabasePrivileges().toJSONString());
                        rdsUserRepository.update(newRdsUser);
                    }
                    content = "rds实例数据库创建成功";
                } else {
                    rdsDbRepository.remove(rdsDb.getId(), context.getTarget());
                }
                resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
                        MapTools.simpleMap(Common.VENDORID, cloudVendor.getId()),
                        OperateResult.OperateCategory.ResourceEvent, context));
            });
            return new BocloudResult(true, "任务已下发，正在执行......");
        } catch (Exception e) {
            logger.error("create rds instance db is error：", e);
            return new BocloudResult(false, "rds实例数据库创建失败");
        }
    }

    @Override
    public BocloudResult getUsers(Pager pager) {
        GridBean gridBean = null;
        try {
            int page = pager.getPage();
            int rows = pager.getRows();
            List<Param> params = pager.getParams();
            Map<String, String> sorter = pager.getSorter();
            boolean simple = pager.getSimple();

            if (null == params) {
                params = Lists.newArrayList();
            }
            if (null == sorter) {
                sorter = Maps.newHashMap();
            }
            sorter.put("gmtCreate", Common.ONE);
            int total = this.rdsUserRepository.count(params);
            if (simple) {
                List<SimpleBean> beans = this.rdsUserRepository.list(params, sorter);
                gridBean = new GridBean(1, 1, total, beans);
            } else {
                List<RdsUser> partitions = this.rdsUserRepository.list(page, rows, params, sorter);
                gridBean = GridHelper.getBean(page, rows, total, partitions);
            }
            return new BocloudResult(true, gridBean, "查询成功");
        } catch (Exception e) {
            logger.error("Query dbInstance user list fail:", e);
            return new BocloudResult(false, "查询失败");
        }
    }

    @Override
    public BocloudResult getDbs(Pager pager) {
        GridBean gridBean = null;
        try {
            int page = pager.getPage();
            int rows = pager.getRows();
            List<Param> params = pager.getParams();
            Map<String, String> sorter = pager.getSorter();
            boolean simple = pager.getSimple();

            if (null == params) {
                params = Lists.newArrayList();
            }
            if (null == sorter) {
                sorter = Maps.newHashMap();
            }
            sorter.put("gmtCreate", Common.ONE);
            int total = this.rdsDbRepository.count(params);
            if (simple) {
                List<SimpleBean> beans = this.rdsDbRepository.list(params, sorter);
                gridBean = new GridBean(1, 1, total, beans);
            } else {
                List<RdsDb> partitions = this.rdsDbRepository.list(page, rows, params, sorter);
                gridBean = GridHelper.getBean(page, rows, total, partitions);
            }
            return new BocloudResult(true, gridBean, "查询成功");
        } catch (Exception e) {
            logger.error("Query dbInstance db list fail:", e);
            return new BocloudResult(false, "查询失败");
        }
    }

    @Override
    public BocloudResult deleteUser(Long id, Long userId, RequestContext context) {
        try {
            RdsPublicCloudInstance instance = rdsPublicCloudInstanceRepository.query(id);
            if (null == instance) {
                logger.info("db instance is not exist!");
                return new BocloudResult(false, "rds实例不存在");
            }
            CloudVendor cloudVendor = cloudVendorRepository.query(instance.getVendorId());
            if (null == cloudVendor) {
                logger.info("cloud vendor is not exist!");
                return new BocloudResult(false, "云平台不存在");
            }
            RdsUser user = rdsUserRepository.query(userId);
            if (null == user) {
                logger.info("db instance user is not exist!");
                return new BocloudResult(false, "rds实例用户不存在");
            }
            BocloudResult result = databaseDriver.deleteAccount(cloudVendor.getUuid(), instance.getRegionId(),
                    instance.getInstanceId(), user.getUsername());
            if (result.isFailed()) {
                logger.error("delete rds instance user is error：", result.getMessage());
                return new BocloudResult(false, "删除失败");
            }
            rdsUserRepository.remove(userId, context.getTarget());
            List<JSONObject> privilegesArrays = JSONObject.parseArray(user.getPrivileges(), JSONObject.class);
            if (!ListTool.isEmpty(privilegesArrays)) {
                for (JSONObject jsonObject : privilegesArrays) {
                    String name = jsonObject.getString("name");
                    RdsDb rdsDb = rdsDbRepository.queryByName(name,cloudVendor.getId(), instance.getId());
                    if (null != rdsDb) {
                        rdsDb.setAccounts(null);
                        rdsDbRepository.update(rdsDb);
                    }
                }
            }

            return new BocloudResult(true, "删除成功");
        } catch (Exception e) {
            logger.error("delete rds instance user is error：", e);
            return new BocloudResult(false, "rds实例用户删除失败");
        }
    }

    @Override
    public BocloudResult deleteDb(Long id, Long dbId, RequestContext context) {
        try {
            RdsPublicCloudInstance instance = rdsPublicCloudInstanceRepository.query(id);
            if (null == instance) {
                logger.info("db instance is not exist!");
                return new BocloudResult(false, "rds实例不存在");
            }
            CloudVendor cloudVendor = cloudVendorRepository.query(instance.getVendorId());
            if (null == cloudVendor) {
                logger.info("cloud vendor is not exist!");
                return new BocloudResult(false, "云平台不存在");
            }
            RdsDb db = rdsDbRepository.query(dbId);
            if (null == db) {
                logger.info("db instance db is not exist!");
                return new BocloudResult(false, "rds实例数据库不存在");
            }
            BocloudResult result = databaseDriver.deleteDatabase(cloudVendor.getUuid(), instance.getRegionId(),
                    instance.getInstanceId(), db.getName());
            if (result.isFailed()) {
                logger.error("delete rds instance db is error：", result.getMessage());
                return new BocloudResult(false, "删除失败");
            }
            List<JSONObject> accountArrays = JSONObject.parseArray(db.getAccounts(), JSONObject.class);
            if (!ListTool.isEmpty(accountArrays)) {
                for (JSONObject jsonObject : accountArrays) {
                    String account = jsonObject.getString("account");
                    RdsUser rdsUser = rdsUserRepository.queryByUserName(account, cloudVendor.getId(), instance.getId());
                    if (null != rdsUser) {
                        List<JSONObject> privilegesArrays = JSONObject.parseArray(rdsUser.getPrivileges(),
                                JSONObject.class);
                        if (!ListTool.isEmpty(privilegesArrays)) {
                            for (int i = privilegesArrays.size() - 1; i >= 0; i--) {
                                JSONObject accountObject = privilegesArrays.get(i);
                                if (account.equalsIgnoreCase(accountObject.getString("account"))) {
                                    privilegesArrays.remove(accountObject);
                                }
                            }
                            rdsUser.setPrivileges(JSON.toJSONString(privilegesArrays));
                            rdsUserRepository.update(rdsUser);
                        }
                    }
                }
            }
            rdsDbRepository.remove(dbId, context.getTarget());
            return new BocloudResult(true, "删除成功");
        } catch (Exception e) {
            logger.error("delete rds instance db is error：", e);
            return new BocloudResult(false, "rds实例用户删除失败");
        }
    }

    @Override
    public BocloudResult resetAccountPassword(Long id, RdsUser rdsUser, RequestContext context) {
        try {
            RdsPublicCloudInstance instance = rdsPublicCloudInstanceRepository.query(id);
            if (null == instance) {
                logger.info("db instance is not exist!");
                return new BocloudResult(false, "rds实例不存在");
            }
            Long vendorId = instance.getVendorId();
            CloudVendor vendor = cloudVendorRepository.query(vendorId);
            if (null == vendor) {
                logger.info("cloud vendor is not exist!");
                return new BocloudResult(false, "云平台不存在");
            }
            RdsUser user = rdsUserRepository.query(rdsUser.getUserId());
            if (null == user) {
                logger.info("db instance user is not exist!");
                return new BocloudResult(false, "用户不存在");
            }
            String password = rdsUser.getPassword();
            Encryptor encryptor = new AESEncrptor();
            password = encryptor.decrypt(password, null);
            BocloudResult result = databaseDriver.resetAccountPassword(vendor.getUuid(), instance.getRegionId(),
                    instance.getInstanceId(), user.getUsername(), password);
            if (result.isFailed()) {
                logger.error("rds instance user reset password is error：", result.getMessage());
                return new BocloudResult(false, "密码重置失败");
            }
            encryptor = new DESEncrptor();
            password = encryptor.encrypt(password, "BocloudCMP");
            user.setGmtModify(new Date());
            user.setPassword(password);
            user.setMenderId(context.getTarget());
            rdsUserRepository.update(rdsUser);
            return new BocloudResult(true, "密码重置成功");
        } catch (Exception e) {
            logger.error("rds instance user reset password is error：", e);
            return new BocloudResult(false, "密码重置失败");
        }
    }

    @Override
    public BocloudResult reset(Long id, RdsUser rdsUser, RequestContext context) {
        RdsPublicCloudInstance instance = rdsPublicCloudInstanceRepository.query(id);
        if (null == instance) {
            logger.info("db instance is not exist!");
            return new BocloudResult(false, "rds实例不存在");
        }
        Long vendorId = instance.getVendorId();
        CloudVendor vendor = cloudVendorRepository.query(vendorId);
        if (null == vendor) {
            logger.info("cloud vendor is not exist!");
            return new BocloudResult(false, "云平台不存在");
        }
        RdsUser user = rdsUserRepository.query(rdsUser.getId());
        if (null == user) {
            logger.info("db instance user is not exist!");
            return new BocloudResult(false, "用户不存在");
        }
        try {
            List<JSONObject> oldData = JSONArray.parseArray(user.getPrivileges(), JSONObject.class);
            Map<String, String> map = Maps.newHashMap();
            for (JSONObject oldDatum : oldData) {
                map.put(oldDatum.getString("name"), oldDatum.getString("accountPrivilege"));
            }
            List<JSONObject> newData = JSONArray.parseArray(rdsUser.getPrivileges(), JSONObject.class);
            for (JSONObject newDatum : newData) {
                if (map.containsKey(newDatum.getString("name"))) {
                    BocloudResult result = databaseDriver.grantAccountPrivilege(vendor.getUuid(),
                            instance.getRegionId(), instance.getInstanceId(), user.getUsername(),
                            newDatum.getString("name"), newDatum.getString("accountPrivilege"));
                    if (result.isFailed()) {
                        logger.error("rds instance user grant password is error：", result.getMessage());
                        return new BocloudResult(false, "授权失败");
                    }
                    map.remove(newDatum.getString("name"));
                }
            }
            for (String name : map.keySet()) {
                BocloudResult result = databaseDriver.revokeAccountPrivilege(vendor.getUuid(), instance.getRegionId(),
                        instance.getInstanceId(), user.getUsername(), name);
                if (result.isFailed()) {
                    logger.error("rds instance user grant password is error：", result.getMessage());
                    return new BocloudResult(false, "授权失败");
                }
            }
            return new BocloudResult(true, "授权成功");
        } catch (Exception e) {
            logger.error("rds instance user grant password is error：", e);
            return new BocloudResult(false, "授权失败");
        } finally {
            BocloudResult bocloudResult = databaseDriver.getAccount(vendor.getUuid(), instance.getRegionId(),
                    instance.getInstanceId(), user.getName());
            DbInstanceUserModel model = (DbInstanceUserModel) bocloudResult.getData();
            user.setPrivileges(model.getDatabasePrivileges().toJSONString());
            user.setGmtModify(new Date());
            user.setMenderId(context.getTarget());
            rdsUserRepository.update(user);
        }
    }

    @Override
    public BocloudResult resetAccount(Long id, RdsUser rdsUser, RequestContext context) {
        try {
            RdsPublicCloudInstance instance = rdsPublicCloudInstanceRepository.query(id);
            if (null == instance) {
                logger.info("db instance is not exist!");
                return new BocloudResult(false, "rds实例不存在");
            }
            Long vendorId = instance.getVendorId();
            CloudVendor vendor = cloudVendorRepository.query(vendorId);
            if (null == vendor) {
                logger.info("cloud vendor is not exist!");
                return new BocloudResult(false, "云平台不存在");
            }
            RdsUser user = rdsUserRepository.query(rdsUser.getUserId());
            if (null == user) {
                logger.info("db instance user is not exist!");
                return new BocloudResult(false, "用户不存在");
            }
            String password = rdsUser.getPassword();
            Encryptor encryptor = new AESEncrptor();
            password = encryptor.decrypt(password, null);
            BocloudResult result = databaseDriver.resetAccount(vendor.getUuid(), instance.getRegionId(),
                    instance.getInstanceId(), user.getUsername(), password);
            if (result.isFailed()) {
                logger.error("rds instance super user reset account is error：", result.getMessage());
                return new BocloudResult(false, "高级权限用户重置失败 ： " + result.getMessage());
            }
            user.setGmtModify(new Date());
            user.setMenderId(context.getTarget());
            rdsUserRepository.update(user);
            return new BocloudResult(true, "高级权限用户重置成功");
        } catch (Exception e) {
            logger.error("rds instance super user reset account is error：", e);
            return new BocloudResult(false, "高级权限用户重置失败");
        }
    }

    @Override
    public BocloudResult restart(Long id, RequestContext context) {
        try {
            RdsPublicCloudInstance instance = rdsPublicCloudInstanceRepository.query(id);
            if (null == instance) {
                logger.info("db instance is not exist!");
                return new BocloudResult(false, "rds实例不存在");
            }
            Long vendorId = instance.getVendorId();
            CloudVendor vendor = cloudVendorRepository.query(vendorId);
            if (null == vendor) {
                logger.info("cloud vendor is not exist!");
                return new BocloudResult(false, "云平台不存在");
            }
            taskExecutor.execute(() -> {
                String operate = vendor.getType().toLowerCase() + ".rds.restart";
                String content = "rds实例重启失败";
                Boolean isSuccess = false;
                BocloudResult result = databaseDriver.restartDBInstance(vendor.getUuid(), instance.getRegionId(),
                        instance.getInstanceId());
                if (result.isSuccess()) {
                    try {
                        while (true) {
                            Thread.sleep(5000);
                            BocloudResult bocloudResult = databaseDriver.detail(instance.getInstanceId(),
                                    vendor.getUuid(), instance.getRegionId());
                            if (bocloudResult.isSuccess()) {
                                DbInstanceModel model = (DbInstanceModel) bocloudResult.getData();
                                if (RdsInstanceStatus.Running.name().equals(model.getStatus())) {
                                    isSuccess = true;
                                    content = "rds实例重启成功";
                                    instance.setStatus(RdsInstanceStatus.Running.name());
                                    instance.setGmtModify(new Date());
                                    instance.setMenderId(context.getTarget());
                                    break;
                                }
                            } else {
                                logger.error(bocloudResult.getMessage());
                                break;
                            }
                        }
                    } catch (Exception e) {
                        logger.error("restart is error:", e);
                    }
                }
                if (!isSuccess) {
                    instance.setStatus(RdsInstanceStatus.RebootFailed.name());
                    instance.setGmtModify(new Date());
                    instance.setMenderId(context.getTarget());
                }
                rdsPublicCloudInstanceRepository.update(instance);
                resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
                        MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                        OperateResult.OperateCategory.ResourceEvent, context));
            });
            instance.setStatus(RdsInstanceStatus.Rebooting.name());
            instance.setMenderId(context.getTarget());
            instance.setGmtModify(new Date());
            rdsPublicCloudInstanceRepository.update(instance);
            return new BocloudResult(true, "rds实例重启任务已下发");
        } catch (Exception e) {
            logger.error("restart is error：", e);
            return new BocloudResult(false, "rds实例重启失败");
        }
    }

    @Override
    public BocloudResult create(RdsPublicCloudInstance instance, RequestContext context) {
        try {
            Long vendorId = instance.getVendorId();
            CloudVendor cloudVendor = cloudVendorRepository.query(vendorId);
            if (null == cloudVendor) {
                return new BocloudResult(false, "云平台不存在");
            }
            String flavorId = instance.getFlavorId();
            RdsPublicCloudFlavor flavor = rdsPublicCLoudFlavorRepository.query(Long.valueOf(flavorId));
            String paramGroupId = instance.getParamGroupId();
            RdsPublicCloudInstanceParameterGroup parameterGroup = rdsPublicCloudInstanceParameterGroupRepository
                    .query(Long.valueOf(paramGroupId));
            instance.setStatus(RdsInstanceStatus.Creating.name());
            instance.setCreatorId(context.getTarget());
            instance.setGmtCreate(new Date());
            instance.setDeleted(false);
            rdsPublicCloudInstanceRepository.save(instance);
            taskExecutor.execute(() -> {
                String operate = cloudVendor.getType().toLowerCase() + ".rds.create";
                String content = "rds实例创建失败";
                RdsPublicCloudInstance publicCloudInstance = null;
                BocloudResult result = databaseDriver.create(cloudVendor.getUuid(), instance.getRegionId(),
                        convertor(instance, flavor.getFlavorUuid(), parameterGroup.getParameterGroupId()));
                if (result.isSuccess()) {
                    try {
                        DbInstanceModel instanceModel = (DbInstanceModel) result.getData();
                        while (true) {
                            Thread.sleep(30000);
                            BocloudResult bocloudResult = databaseDriver.detail(instanceModel.getInstanceId(),
                                    cloudVendor.getUuid(), instance.getRegionId());
                            DbInstanceModel model = (DbInstanceModel) bocloudResult.getData();
                            if (bocloudResult.isSuccess()) {
                                if (RdsInstanceStatus.Running.name().equals(model.getStatus())) {
                                    content = "rds实例创建成功";
                                    publicCloudInstance = convertor(model, context.getTarget(), cloudVendor);
                                    break;
                                }
                            } else {
                                rdsPublicCloudInstanceRepository.remove(RdsPublicCloudInstance.class,instance.getId());
                                logger.error(bocloudResult.getMessage());
                                break;
                            }
                        }
                    } catch (Exception e) {
                        rdsPublicCloudInstanceRepository.remove(RdsPublicCloudInstance.class,instance.getId());
                        logger.error("create is error:", e);
                    }
                }else {
                    rdsPublicCloudInstanceRepository.remove(RdsPublicCloudInstance.class,instance.getId());
                    content = result.getMessage();
                }
                if (null != publicCloudInstance) {
                    publicCloudInstance.setId(instance.getId());
                    rdsPublicCloudInstanceRepository.update(publicCloudInstance);
                }
                resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
                        MapTools.simpleMap(Common.VENDORID, cloudVendor.getId()),
                        OperateResult.OperateCategory.ResourceEvent, context));
            });
            return new BocloudResult(true, "任务已下发，正在执行......");
        } catch (Exception e) {
            logger.error("create rds instance is error：", e);
            return new BocloudResult(false, "rds实例创建失败");
        }
    }

    private RdsPublicCloudInstance convertor(DbInstanceModel model, Long userId, CloudVendor vendor) {
        RdsPublicCloudInstance rds = new RdsPublicCloudInstance();
        BeanUtils.copyProperties(model, rds);
        rds.setInstanceId(model.getInstanceId());
        rds.setRegion(model.getRegionId());
        rds.setAvailZone(model.getZoneId());
        rds.setDataStoreType(model.getEngine());
        rds.setDataStoreVersion(model.getVersion());
        rds.setName(model.getName());
        rds.setVswitchId(model.getVswitchId());
        rds.setVpcCloudInstanceId(model.getVpcCloudInstanceId());
        rds.setVolSize(model.getDbInstanceStorage());
        rds.setType(model.getInstanceType()); // 主备
        rds.setCategory(model.getCategory());
        rds.setCreatorId(userId);
        rds.setGmtCreate(new Date());
        rds.setVendorId(vendor.getId());
        rds.setVendorType(vendor.getType());
        rds.setFlavorId(model.getInstanceClass());
        rds.setVolSize(model.getDisk());
        // M转换GB
        if (null != model.getMemory()) {
            rds.setMemory(model.getMemory().longValue() / 1024);
        }
        // 内网连接地址
        rds.setDnsName(model.getConnectionString());
        rds.setDbPort(model.getPort());
        rds.setVpcId(model.getVpcId());
        rds.setInstanceNetworkType(model.getNetworkType());
        rds.setCategory(model.getCategory());
        rds.setDbInstanceNetType(model.getNetType());
        rds.setMaxIops(model.getMaxIOPS());
        rds.setVpcCloudInstanceId(model.getVpcCloudInstanceId());
        rds.setPeriod(model.getPeriod());
        rds.setUsedTime(model.getUsedTime());
        rds.setResourceId(model.getResourceId());
        rds.setAutoRenew(model.getAutoRenew());
        rds.setParamGroupId(model.getDBParamGroupId());
        rds.setTimeZone(model.getDBTimeZone());
        rds.setIgnoreCase(model.getDBIsIgnoreCase());
        rds.setDeleted(false);
        return rds;
    }

    private DbInstanceModel convertor(RdsPublicCloudInstance instance, String flavorUuid, String paramGroup) {
        DbInstanceModel model = new DbInstanceModel();
        BeanUtils.copyProperties(instance, model);
        model.setEngine(instance.getType());
        model.setVersion(instance.getDataStoreVersion());
        model.setInstanceClass(flavorUuid);
        model.setDbInstanceStorage(instance.getVolSize());
        model.setDBInstanceNetType(null == instance.getVpcId() ? "Internet" : "Intranet");
        model.setName(instance.getName());
        model.setPayType(instance.getPayType());
        model.setZoneId(instance.getAvailZone());
        model.setInstanceNetworkType(instance.getInstanceNetworkType());
        model.setVpcId(instance.getVpcId());
        model.setVswitchId(instance.getVswitchId());
        model.setPeriod(instance.getPeriod());
        model.setUsedTime(instance.getUsedTime());
        model.setResourceId(instance.getResourceId());
        model.setDbInstanceStorageType(instance.getVolType());
        model.setAutoRenew(instance.getAutoRenew());
        model.setDBParamGroupId(paramGroup);
        model.setDBTimeZone(instance.getTimeZone());
        model.setDBIsIgnoreCase(instance.getIgnoreCase());
        return model;
    }

    @Override
    public BocloudResult delete(Long id, RequestContext context) {
        try {
            RdsPublicCloudInstance instance = rdsPublicCloudInstanceRepository.query(id);
            if (null == instance) {
                logger.info("db instance is not exist!");
                return new BocloudResult(false, "rds实例不存在");
            }
            Long vendorId = instance.getVendorId();
            CloudVendor vendor = cloudVendorRepository.query(vendorId);
            if (null == vendor) {
                logger.info("cloud vendor is not exist!");
                return new BocloudResult(false, "云平台不存在");
            }
            BocloudResult result = databaseDriver.remove(instance.getInstanceId(), vendor.getUuid(),
                    instance.getRegionId());
            if (result.isFailed()) {
                logger.error(result.getMessage());
                return new BocloudResult(false, "实例释放失败：" + result.getMessage());
            }
            rdsDbRepository.removeByVidAndRdsId(vendorId, instance.getId(), context.getTarget());
            rdsUserRepository.removeByVidAndRdsId(vendorId, instance.getId(), context.getTarget());
            rdsPublicCloudInstanceRepository.delete(instance.getId(), context.getTarget());
            return new BocloudResult(true, "实例释放成功");
        } catch (Exception e) {
            logger.error("delete db instance is error：", e);
            return new BocloudResult(false, "实例释放失败:" + e.getMessage());
        }
    }

    private void converter(RdsPublicCloudInstance rdsPublicCloud) {
        if (StringUtils.isNotBlank(rdsPublicCloud.getDBInstanceClassType())) {
            rdsPublicCloud.setDBInstanceClassType(CacheMode.byValue(rdsPublicCloud.getDBInstanceClassType()));
        }
        if (StringUtils.isNotBlank(rdsPublicCloud.getPayType())) {
            rdsPublicCloud.setPayType(CacheMode.byValue(rdsPublicCloud.getPayType()));
        }
        if (StringUtils.isNotBlank(rdsPublicCloud.getAutoUpgradeMinorVersion())) {
            rdsPublicCloud.setAutoUpgradeMinorVersion(CacheMode.byValue(rdsPublicCloud.getAutoUpgradeMinorVersion()));
        }
        if (StringUtils.isNotBlank(rdsPublicCloud.getVolType())) {
            rdsPublicCloud.setVolType(CacheMode.byValue(rdsPublicCloud.getVolType()));
        }
    }

    @Override
    public BocloudResult getErrLog(String params, RequestContext user) {
//        JSONObject object = JSONTools.isJSONObj(params);
//        if (object == null) {
//            return new BocloudResult(false, "参数格式不正确");
//        }
//        DbInstanceModel rds = JSONObject.parseObject(params, DbInstanceModel.class);
//        /*try {
//            SimpleDateFormat normalSdf = new SimpleDateFormat(CmpCommon.TIME_PATTERN);
//            SimpleDateFormat aliSdf = new SimpleDateFormat(CmpCommon.TIME_PATTERN_Z);
//
//            Date startRawDate = normalSdf.parse(rds.getStart_date());
//            Date endRawDate = normalSdf.parse(rds.getEnd_date());
//
//            rds.setStart_date(aliSdf.format(startRawDate).toString());
//            rds.setEnd_date(aliSdf.format(endRawDate).toString());
//
//        } catch (ParseException e1) {
//            logger.error("Query errorLog By RdsModel(" + rds.toString() + ")  message：", e1);
//            return new BocloudResult(false, "请求日期格式解析异常。");
//        }*/
//        try {
//
//            RdsPublicCloudInstance rds1 = rdsPublicCloudInstanceRepository.queryByInsId(rds.getInstanceId());
//            if (null == rds1) {
//                logger.info("db instance is not exist!");
//                return new BocloudResult(false, "实例不存在");
//            }
//            Long vendorId = rds1.getVendorId();
//            CloudVendor vendor = cloudVendorRepository.query(vendorId);
//            if (null == vendor) {
//                logger.info("cloud vendor is not exist!");
//                return new BocloudResult(false, "云平台不存在");
//            }
//            return databaseDriver.getErrLog(rds, vendor.getUuid(), "");
//        } catch (Exception e) {
//            logger.error("Query errorLog By RdsModel(" + rds.toString() + ")  message：", e);
//            return new BocloudResult(false, "请求查询错误日志失败.");
//        }
        return null;
    }

    @Override
    public BocloudResult getSlowLog(String params, RequestContext user) {
//        JSONObject object = JSONTools.isJSONObj(params);
//        if (object == null) {
//            return new BocloudResult(false, "参数格式不正确");
//        }
//        DbInstanceModel rds = JSONObject.parseObject(params, DbInstanceModel.class);
//        /*try {
//            SimpleDateFormat normalSdf = new SimpleDateFormat(CmpCommon.TIME_PATTERN);
//            SimpleDateFormat aliSdf = new SimpleDateFormat(CmpCommon.TIME_PATTERN_Z);
//
//            Date startRawDate = normalSdf.parse(rds.getStart_date());
//            Date endRawDate = normalSdf.parse(rds.getEnd_date());
//
//            rds.setStart_date(aliSdf.format(startRawDate).toString());
//            rds.setEnd_date(aliSdf.format(endRawDate).toString());
//
//        } catch (ParseException e1) {
//            logger.error("Query errorLog By RdsModel(" + rds.toString() + ")  message：", e1);
//            return new BocloudResult(false, "请求日期格式解析异常。");
//        }*/
//        try {
//            RdsPublicCloudInstance rdsPublicCloudInstance = rdsPublicCloudInstanceRepository.queryByInsId(rds.getInstanceId());
//            if (null == rdsPublicCloudInstance) {
//                logger.info("db instance is not exist!");
//                return new BocloudResult(false, "实例不存在");
//            }
//            Long vendorId = rdsPublicCloudInstance.getVendorId();
//            CloudVendor vendor = cloudVendorRepository.query(vendorId);
//            if (null == vendor) {
//                logger.info("cloud vendor is not exist!");
//                return new BocloudResult(false, "云平台不存在");
//            }
//            return databaseDriver.getSlowLog(rds, vendor.getUuid(), "");
//        } catch (Exception e) {
//            logger.error("Query slowLog By RdsModel(" + rds.toString() + ")  message：", e);
//            return new BocloudResult(false, "请求查询慢日志失败.");
//        }
        return null;
    }

    @Override
    public BocloudResult getRegions(Long vendorId, String type, String volType) {
        CloudVendor vendor = cloudVendorRepository.query(vendorId);
        if (null == vendor) {
            logger.info("cloud vendor is not exist!");
            return new BocloudResult(false, "云平台不存在");
        }
        JSONObject authentication = JSONObject.parseObject(vendor.getAuthentication());
        String regions = authentication.getString("regions");
        List<String> currentRegions = JSONObject.parseArray(regions, String.class);
        if (ListTool.isEmpty(currentRegions)) {
            return new BocloudResult(false, "查询云平台区域信息失败！");
        }
        BocloudResult bocloudResult = databaseDriver.getRegions(vendor.getUuid(), currentRegions.get(0), type, volType);
        if (bocloudResult.isFailed()) {
            logger.error(bocloudResult.getMessage());
            return new BocloudResult(false, "查询失败");
        }
        return new BocloudResult(true, bocloudResult.getData(), "查询成功");
    }

    @Override
    public BocloudResult flavors(String category, Long vendorId, String regionId, String zone, String engine,
                                 String version, String volType, String payType) {
        try {
            List<RdsPublicCloudFlavor> flavors = rdsPublicCLoudFlavorRepository.list(category, vendorId, regionId, zone,
                    engine, version, volType, payType);
            return new BocloudResult(true, flavors, "查询成功");
        } catch (Exception e) {
            logger.error("query flavors is error：", e);
            return new BocloudResult(false, "查询失败 :" + e.getMessage());
        }
    }

    @Override
    public BocloudResult paramGroups(Long vendorId, String regionId, String engine, String version) {
        try {
            List<RdsPublicCloudInstanceParameterGroup> groups = rdsPublicCloudInstanceParameterGroupRepository
                    .list(vendorId, regionId, engine, version);
            return new BocloudResult(true, groups, "查询成功");
        } catch (Exception e) {
            logger.error("query param groups is error：", e);
            return new BocloudResult(false, "查询失败:" + e.getMessage());
        }
    }

}