package com.purui.prims.headless.server.service;

import com.google.common.collect.Lists;
import com.purui.prims.common.pojo.DataFormat;
import com.purui.prims.common.pojo.enums.DataFormatTypeEnum;
import com.purui.prims.common.pojo.enums.SensitiveLevelEnum;
import com.purui.prims.common.pojo.enums.StatusEnum;
import com.purui.prims.common.pojo.enums.TypeEnums;
import com.purui.prims.headless.api.pojo.DrillDownDimension;
import com.purui.prims.headless.api.pojo.MeasureParam;
import com.purui.prims.headless.api.pojo.MetricDefineByMeasureParams;
import com.purui.prims.headless.api.pojo.RelateDimension;
import com.purui.prims.headless.api.pojo.enums.MetricDefineType;
import com.purui.prims.headless.api.pojo.enums.MetricType;
import com.purui.prims.headless.api.pojo.request.MetricReq;
import com.purui.prims.headless.api.pojo.response.MetricResp;
import com.purui.prims.headless.api.pojo.response.ModelResp;
import com.purui.prims.headless.server.persistence.dataobject.MetricDO;
import com.purui.prims.headless.server.persistence.repository.MetricRepository;
import com.purui.prims.headless.server.utils.MetricConverter;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import java.util.HashMap;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

public class MetricServiceImplTest {

    @Test
    void createMetric() throws Exception {
        ModelService modelService = Mockito.mock(ModelService.class);
        MetricReq metricReq = buildMetricReq();
        when(modelService.getModel(metricReq.getModelId())).thenReturn(mockModelResp());
        when(modelService.getModelByDomainIds(any())).thenReturn(Lists.newArrayList());
    }

    @Test
    void updateMetric() throws Exception {
        MetricRepository metricRepository = Mockito.mock(MetricRepository.class);
        ModelService modelService = Mockito.mock(ModelService.class);
        MetricReq metricReq = buildMetricUpdateReq();
        when(modelService.getModel(metricReq.getModelId())).thenReturn(mockModelResp());
        when(modelService.getModelByDomainIds(any())).thenReturn(Lists.newArrayList());
        MetricDO metricDO = MetricConverter.convert2MetricDO(buildMetricReq());
        when(metricRepository.getMetricById(metricDO.getId())).thenReturn(metricDO);
    }

    private MetricReq buildMetricReq() {
        MetricReq metricReq = new MetricReq();
        metricReq.setId(1L);
        metricReq.setName("hr部门的访问次数");
        metricReq.setBizName("pv");
        metricReq.setAlias("pv");
        metricReq.setMetricDefineType(MetricDefineType.MEASURE);
        metricReq.setModelId(2L);
        metricReq.setDataFormatType(DataFormatTypeEnum.PERCENT.name());
        DataFormat dataFormat = new DataFormat();
        dataFormat.setDecimalPlaces(3);
        dataFormat.setNeedMultiply100(false);
        metricReq.setDataFormat(dataFormat);
        MetricDefineByMeasureParams typeParams = new MetricDefineByMeasureParams();
        typeParams.setMeasures(Lists.newArrayList(
            new MeasureParam("pr_pv", "department='hr'"),
            new MeasureParam("pr_uv", "department='hr'")));
        typeParams.setExpr("pr_pv/pr_uv");
        metricReq.setMetricDefineByMeasureParams(typeParams);
        metricReq.setClassifications(Lists.newArrayList("核心指标"));
        metricReq.setRelateDimension(
            RelateDimension.builder().drillDownDimensions(Lists.newArrayList(
                new DrillDownDimension(1L),
                new DrillDownDimension(1L, false))
            ).build());
        metricReq.setSensitiveLevel(SensitiveLevelEnum.LOW.getCode());
        metricReq.setExt(new HashMap<>());
        return metricReq;
    }

    private MetricResp buildExpectedMetricResp() {
        MetricResp metricResp = new MetricResp();
        metricResp.setId(1L);
        metricResp.setName("hr部门的访问次数");
        metricResp.setBizName("pv");
        metricResp.setAlias("pv");
        metricResp.setMetricDefineType(MetricDefineType.MEASURE);
        metricResp.setModelId(2L);
        metricResp.setDataFormatType(DataFormatTypeEnum.PERCENT);
        DataFormat dataFormat = new DataFormat();
        dataFormat.setDecimalPlaces(3);
        dataFormat.setNeedMultiply100(false);
        metricResp.setDataFormat(dataFormat);
        MetricDefineByMeasureParams typeParams = new MetricDefineByMeasureParams();
        typeParams.setMeasures(Lists.newArrayList(
            new MeasureParam("pr_pv", "department='hr'"),
            new MeasureParam("pr_uv", "department='hr'")));
        typeParams.setExpr("pr_pv/pr_uv");
        metricResp.setMetricDefineByMeasureParams(typeParams);
        metricResp.setClassifications("核心指标");
        metricResp.setRelateDimension(
            RelateDimension.builder().drillDownDimensions(Lists.newArrayList(
                new DrillDownDimension(1L),
                new DrillDownDimension(1L, false))
            ).build());
        metricResp.setSensitiveLevel(SensitiveLevelEnum.LOW.getCode());
        metricResp.setExt(new HashMap<>());
        metricResp.setTypeEnum(TypeEnums.METRIC);
        metricResp.setIsCollect(false);
        metricResp.setType(MetricType.DERIVED.name());
        metricResp.setStatus(StatusEnum.ONLINE.getCode());
        return metricResp;
    }

    private MetricReq buildMetricUpdateReq() {
        MetricReq metricReq = new MetricReq();
        metricReq.setId(1L);
        metricReq.setName("hr部门的访问次数");
        metricReq.setBizName("pv");
        metricReq.setMetricDefineType(MetricDefineType.MEASURE);
        MetricDefineByMeasureParams typeParams = new MetricDefineByMeasureParams();
        typeParams.setMeasures(Lists.newArrayList(
            new MeasureParam("pr_pv", "department='hr'"),
            new MeasureParam("pr_uv", "department='hr'")));
        typeParams.setExpr("pr_pv/pr_uv");
        metricReq.setMetricDefineByMeasureParams(typeParams);
        return metricReq;
    }

    private ModelResp mockModelResp() {
        ModelResp modelResp = new ModelResp();
        modelResp.setId(2L);
        modelResp.setDomainId(1L);
        return modelResp;
    }

}
