package com.bocloud.ims.service.resource.azure.db;

import com.bocloud.cmp.driver.azure.db.DbConfigurationDriver;
import com.bocloud.cmp.model.azure.db.DbConfigurationModel;
import com.bocloud.common.model.*;
import com.bocloud.common.utils.MapTools;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.ResourceGroup;
import com.bocloud.ims.entity.resource.azure.db.AzureDatabaseServer;
import com.bocloud.ims.entity.resource.azure.db.DbConfiguration;
import com.bocloud.ims.interfaces.resource.azure.db.DbConfigurationService;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.ResourceGroupRepository;
import com.bocloud.ims.repository.resource.azure.db.CloudDatabaseServerRepository;
import com.bocloud.ims.repository.resource.azure.db.DbConfigurationRepository;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @Company: 博云 www.bocloud.com
 * @ClassName: DbConfigurationServiceImpl
 * @Description:
 * @author: zhenpingLi/李振平
 * @date: 2021/2/4 18:08
 */
@Service("dbConfigurationService")
public class DbConfigurationServiceImpl implements DbConfigurationService {

    private static OperateResult.OperateCategory operateCategory = OperateResult.OperateCategory.ResourceEvent;
    private static Logger logger = LoggerFactory.getLogger(DbConfigurationServiceImpl.class);

    @Autowired
    private DbConfigurationRepository dbConfigurationRepository;
    @Autowired
    private DbConfigurationDriver dbConfigurationDriver;
    @Autowired
    private CloudDatabaseServerRepository cloudDatabaseServerRepository;
    @Autowired
    private CloudVendorRepository vendorRepository;
    @Autowired
    private ResourceGroupRepository resourceGroupRepository;
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    private ResourceEventPublisher resourceEventPublisher;


    @Override
    public BocloudResult<Void> create(DbConfiguration entityParams, RequestContext context) {
        return null;
    }

    public BocloudResult<Void> modify(Long id, String value, RequestContext context) {
        try {
            DbConfiguration entity = dbConfigurationRepository.query(id);
            Assert.notNull(entity, "资源不存在");
            AzureDatabaseServer databaseServer = cloudDatabaseServerRepository.query(entity.getDatabaseServerId());
            Assert.notNull(databaseServer, "所属服务器不存在");
            CloudVendor vendor = vendorRepository.query(databaseServer.getVendorId());
            Assert.notNull(vendor, "平台不存在");
            ResourceGroup resourceGroup = resourceGroupRepository.query(databaseServer.getResourceGroupId());
            Assert.notNull(resourceGroup, "资源组不存在");

            DbConfigurationModel model = new DbConfigurationModel();
            model.setResourceGroupName(resourceGroup.getName());
            model.setDatabaseServerName(databaseServer.getName());
            model.setName(entity.getName());
            model.setConfigurationValue(value);
            model.setSource("user-override");

            taskExecutor.execute(() -> {
                String operate = vendor.getType().toLowerCase() + ".dbconfiguration";
                String message = "修改配置失败";
                BocloudResult result = dbConfigurationDriver.createOrUpdate(vendor.getUuid(), databaseServer.getRegionId(), model);
                try {
                    if (result.isSuccess()) {
                        message = "修改配置成功";
                        entity.setConfigurationValue(value);
                        entity.setSource("user-override");
                        dbConfigurationRepository.update(entity);
                    } else {
                        logger.error("修改配置失败：" + result.getMessage());
                        message = result.getMessage();
                    }
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), message, operate,
                            MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                } catch (Exception e) {
                    logger.error("create databaseServer fail:", e);
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), message, operate, MapTools.simpleMap(
                            "vendorId", vendor.getId()), operateCategory, context));
                }
            });
            return new BocloudResult<>(true, "任务已下发，正在执行...");
        } catch (Exception e) {
            logger.error("modify DbConfiguration error!", e);
            return new BocloudResult<>(false, "修改失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult<GridBean<DbConfiguration>> list(Pager pager, RequestContext context) {
        List<Param> params = Optional.ofNullable(pager.getParams()).orElse(new ArrayList<>());
        Map<String, String> sorter = Optional.ofNullable(pager.getSorter()).orElse(Maps.newHashMap());
        Boolean simple = Optional.ofNullable(pager.getSimple()).orElse(false);
        Integer page = Optional.ofNullable(pager.getPage()).orElse(1);
        Integer rows = Optional.ofNullable(pager.getRows()).orElse(10);
        try {
            int total = dbConfigurationRepository.count(params);
            List<DbConfiguration> list = this.dbConfigurationRepository.list(page, rows, params, sorter);
            GridBean<DbConfiguration> gridBean = new GridBean<>(page, rows, total, list);
            return new BocloudResult<>(true, gridBean, "查询成功");
        } catch (Exception e) {
            logger.error("list DbConfiguration error!", e);
            return new BocloudResult<>(false, "查询失败:" + e.getMessage());
        }
    }
}