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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.monitor.MonitorDriver;
import com.bocloud.cmp.params.azure.CloudMonitorParams;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.RequestContext;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.interfaces.resource.azure.monitor.MonitorService;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.service.model.ResultTrend;
import com.bocloud.ims.service.model.StatsResult;
import com.bocloud.ims.service.model.TrendData;
import com.bocloud.ims.service.utils.DateUtil;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

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

/**
 * @Company: 博云 www.bocloud.com
 * @ClassName: MonitorServiceImpl
 * @Description:
 * @author: zhenpingLi/李振平
 * @date: 2020/12/30 9:41
 */
@Service("monitorService")
public class MonitorServiceImpl implements MonitorService {

    private static Logger logger = LoggerFactory.getLogger(MonitorServiceImpl.class);
    @Autowired
    private MonitorDriver monitorDriver;
    @Autowired
    private CloudVendorRepository vendorRepository;

    @Override
    public BocloudResult<String> metricNamespaces(CloudMonitorParams params, RequestContext context) {
        Long vendorId = params.getVendorId();
        String resourceUri = params.getResourceUri();
        try {
            CloudVendor vendor = vendorRepository.query(vendorId);
            if (ObjectUtils.isEmpty(vendor)) {
                logger.error("get cloudVendor failure");
                return new BocloudResult<>(false, "平台验证失败");
            }
            BocloudResult bocloudResult = monitorDriver.metricNamespaces(vendor.getUuid(), resourceUri);
            return bocloudResult;
        } catch (Exception e) {
            logger.error("list metricNamespaces error!", e);
            return new BocloudResult<>(false, "查询失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult<String> metricDefinitions(CloudMonitorParams params, RequestContext context) {
        Long vendorId = params.getVendorId();
        String resourceUri = params.getResourceUri();
        String metricNamespace = params.getMetricNamespace();
        try {
            CloudVendor vendor = vendorRepository.query(vendorId);
            if (ObjectUtils.isEmpty(vendor)) {
                logger.error("get cloudVendor failure");
                return new BocloudResult<>(false, "平台验证失败");
            }
            BocloudResult bocloudResult = monitorDriver.metricDefinitions(vendor.getUuid(), resourceUri, metricNamespace);
            return bocloudResult;
        } catch (Exception e) {
            logger.error("list metricDefinitions error!", e);
            return new BocloudResult<>(false, "查询失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult<String> metrics(CloudMonitorParams params, RequestContext context) {
        Map<String, String> timeMap = DateUtil.timeToMapUTC(params.getTime());
        // 获取时间
        String unit = timeMap.get("unit");
        String startTime = timeMap.get("start");
        String endTime = timeMap.get("end");

        if (null != unit && !unit.equals("")) {
            startTime = params.getStartTime();
            endTime = params.getEndTime();
        }
        Long vendorId = params.getVendorId();
        String resourceUri = params.getResourceUri();
        String interval = params.getInterval();
        String metricnames = params.getMetricnames();
        metricnames = metricnames.replaceAll(" ", "+");
        String aggregation = params.getAggregation();
        String metricNamespace = params.getMetricNamespace();
        String timespan = startTime + "/" + endTime;
        try {
            CloudVendor vendor = vendorRepository.query(vendorId);
            if (ObjectUtils.isEmpty(vendor)) {
                logger.error("get cloudVendor failure");
                return new BocloudResult<>(false, "平台验证失败");
            }
            BocloudResult bocloudResult = monitorDriver.metrics(vendor.getUuid(), resourceUri, timespan
                    , interval, metricnames, aggregation, metricNamespace);
            String response = (String) bocloudResult.getData();
            JSONObject responseObject = JSONObject.parseObject(response);

            List<String> keys = new ArrayList<>();
            List<String> trendData = Lists.newArrayList();
            List<TrendData> dataList = Lists.newArrayList();

            JSONArray values = responseObject.getJSONArray("value");
            JSONObject value = values.getJSONObject(0);

            String name = value.getJSONObject("name").getString("value");
            JSONArray timeseries = value.getJSONArray("timeseries");
            JSONObject timeserie = timeseries.getJSONObject(0);

            List<StatsResult> statsResults = Optional.ofNullable(timeserie.getJSONArray("data")).map(array -> array.stream()
                    .map(JSON::toJSONString).map(JSON::parseObject).map(obj -> {
                        StatsResult statsResult = new StatsResult();
                        String timeStamp = obj.getString("timeStamp");
                        Double average = obj.getDouble("average") == null ? 0 : obj.getDouble("average");
                        statsResult.setName(timeStamp);
                        statsResult.setValue(average);
                        return statsResult;
                    }).collect(Collectors.toList())
            ).orElse(new ArrayList<>());
            statsResults.stream().forEach(statsResult -> {
                keys.add(statsResult.getName());
                trendData.add(statsResult.getValue() + "");
            });
            dataList.add(new TrendData(name, trendData));
            ResultTrend resultTrend = new ResultTrend(keys, dataList);
            return new BocloudResult(true, resultTrend, "查询成功");
        } catch (Exception e) {
            logger.error("list metrics error!", e);
            return new BocloudResult<>(false, "查询失败:" + e.getMessage());
        }
    }
}