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

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.monitor.AlarmDriver;
import com.bocloud.cmp.model.AlarmModel;
import com.bocloud.common.model.*;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.ListTool;
import com.bocloud.ims.entity.common.Project;
import com.bocloud.ims.entity.resource.CloudServer;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.azure.db.AzureDatabaseServer;
import com.bocloud.ims.entity.resource.azure.monitor.Alarm;
import com.bocloud.ims.entity.resource.azure.monitor.MetricAlert;
import com.bocloud.ims.entity.resource.azure.monitor.MetricAlertResourceRelation;
import com.bocloud.ims.entity.resource.azure.redis.CloudRedis;
import com.bocloud.ims.interfaces.resource.azure.monitor.AlarmService;
import com.bocloud.ims.repository.resource.CloudServerRepository;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.azure.db.CloudDatabaseServerRepository;
import com.bocloud.ims.repository.resource.azure.monitor.AlarmRepository;
import com.bocloud.ims.repository.resource.azure.monitor.MetricAlertRepository;
import com.bocloud.ims.repository.resource.azure.monitor.MetricAlertResourceRelationRepository;
import com.bocloud.ims.repository.resource.azure.redis.CloudRedisRepository;
import com.bocloud.ims.service.internal.SmsProjectService;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;

/**
 * @Company: 博云 www.bocloud.com
 * @ClassName: AlarmServiceImpl
 * @Description:
 * @author: zhenpingLi/李振平
 * @date: 2021/1/20 13:54
 */
@Service("AlarmService")
public class AlarmServiceImpl implements AlarmService {

    private static Logger logger = LoggerFactory.getLogger(AlarmServiceImpl.class);

    @Autowired
    private SmsProjectService smsProjectService;
    @Autowired
    private AlarmRepository alarmRepository;
    @Autowired
    private MetricAlertRepository metricAlertRepository;
    @Autowired
    private AlarmDriver alarmDriver;
    @Autowired
    private CloudVendorRepository vendorRepository;
    @Autowired
    private CloudServerRepository cloudServerRepository;
    @Autowired
    private MetricAlertResourceRelationRepository metricAlertResourceRelationRepository;
    @Autowired
    private CloudRedisRepository cloudRedisRepository;
    @Autowired
    private CloudDatabaseServerRepository cloudDatabaseServerRepository;

    @Override
    public BocloudResult<Void> remove(Long id, RequestContext context) {
        return null;
    }

    @Override
    public BocloudResult<GridBean<Alarm>> 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());
        sorter.put("gmtCreate", Common.ONE);
        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 {
            List<Alarm> list;
            int total;
            GridBean<Alarm> gridBean;
            Long tenantId = context.getTenant();
            Long projectId = context.getProject();

            // 为租户下的用户
            if (null != tenantId && 0L != tenantId) {
                List<Project> projects = smsProjectService.projectsByCondition(context.getTarget(),
                        context.getCatalog());
                List<Long> projectIds = new ArrayList<>();
                // 此时查询的是全部用户全部项目的信息
                if (null != projectId && 0L != projectId) {
                    projectIds.add(projectId);
                } else if (!ListTool.isEmpty(projects)) {
                    projects.forEach(project -> projectIds.add(project.getId()));
                } else {
                    projectIds.add(-1L);
                }
                total = this.alarmRepository.count(params, null, projectIds, null);
                list = this.alarmRepository.list(page, rows, params, sorter, null, projectIds, null);
            } else {
                list = alarmRepository.list(page, rows, params, sorter);
                total = alarmRepository.count(params);
            }
            for (Alarm alarm : list) {
                MetricAlert metricAlert = metricAlertRepository.query(alarm.getMetricAlertId());
                if (!ObjectUtils.isEmpty(metricAlert)) {
                    List<Object> resources = this.getResources(metricAlert);
                    metricAlert.setResources(resources);
                    alarm.setMetricAlert(metricAlert);
                }
            }
            gridBean = new GridBean<>(page, rows, total, list);
            return new BocloudResult<>(true, gridBean, "查询成功");
        } catch (Exception e) {
            logger.error("list Alarm failure:", e);
            return new BocloudResult<>(false, "查询失败:" + e.getMessage());
        }

    }

    private List<Object> getResources(MetricAlert entity) {
        List<Object> objects = new ArrayList<>();
        List<MetricAlertResourceRelation> resourceRelations = metricAlertResourceRelationRepository.listByMetricAlertId(entity.getId());
        for (MetricAlertResourceRelation relation : resourceRelations) {
            switch (relation.getResourceType()) {
                case "Microsoft.Compute/virtualMachines":
                    CloudServer cloudServer = cloudServerRepository.query(relation.getResourceId());
                    if (!ObjectUtils.isEmpty(cloudServer)) {
                        objects.add(cloudServer);
                    }
                    break;
                case "Microsoft.DBForMySQL/servers":
                    AzureDatabaseServer databaseServer = cloudDatabaseServerRepository.query(relation.getResourceId());
                    if (!ObjectUtils.isEmpty(databaseServer)) {
                        objects.add(databaseServer);
                    }
                    break;
                case "Microsoft.Cache/Redis":
                    CloudRedis cloudRedis = cloudRedisRepository.query(relation.getResourceId());
                    if (!ObjectUtils.isEmpty(cloudRedis)) {
                        objects.add(cloudRedis);
                    }
                    break;
                default:
                    break;

            }

        }
        return objects;

    }

    @Override
    public BocloudResult<Alarm> detail(Long id, RequestContext context) {
        try {
            Alarm entity = alarmRepository.query(id);
            MetricAlert metricAlert = metricAlertRepository.query(entity.getMetricAlertId());
            if (!ObjectUtils.isEmpty(metricAlert)) {
                entity.setMetricAlert(metricAlert);
            }
            return new BocloudResult<>(true, entity, "查询详情成功");
        } catch (Exception e) {
            logger.error("query Alarm error!", e);
            return new BocloudResult<>(false, "查询详情失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult<Void> modify(Alarm entityParams, RequestContext context) {
        try {
            String status = entityParams.getStatus();
            Alarm entity = alarmRepository.query(entityParams.getId());
            if (ObjectUtils.isEmpty(entity)) {
                logger.error("get alarm failure");
                return new BocloudResult<>(false, "数据不存在");
            }
            CloudVendor vendor = vendorRepository.query(entity.getVendorId());
            if (ObjectUtils.isEmpty(vendor)) {
                logger.error("get cloudVendor failure");
                return new BocloudResult<>(false, "平台验证失败");
            }

            AlarmModel model = new AlarmModel();
            BeanUtils.copyProperties(entity, model);
            model.setStatus(status);
            BocloudResult bocloudResult = alarmDriver.update(model, vendor.getUuid(), null);
            if (bocloudResult.isFailed()) {
                return new BocloudResult<>(false, "状态调整失败");
            }
            AlarmModel newModel = JSONObject.parseObject(JSONObject.toJSONString(bocloudResult.getData()), AlarmModel.class);
            entity.setStatus(newModel.getStatus());
            entity.setMenderId(context.getTarget());
            entity.setGmtModify(new Date());
            entity.setGmtTrigger(newModel.getGmtTrigger());
            entity.setGmtConfirm(newModel.getGmtConfirm());
            alarmRepository.update(entity);
            return new BocloudResult<>(true, "状态调整成功");
        } catch (Exception e) {
            logger.error("update Alarm error:", e);
            return new BocloudResult<>(false, "状态调整失败:" + e.getMessage());
        }
    }


}