package com.purui.prims.headless.api.pojo.response;

import com.google.common.collect.Lists;
import com.purui.prims.headless.api.pojo.Dim;
import com.purui.prims.headless.api.pojo.DrillDownDimension;
import com.purui.prims.headless.api.pojo.Field;
import com.purui.prims.headless.api.pojo.Identify;
import com.purui.prims.headless.api.pojo.ModelDetail;
import com.purui.prims.headless.api.pojo.SchemaItem;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Data
@ToString(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "模型")
public class ModelResp extends SchemaItem {

    @ApiModelProperty(value = "主题域ID")
    private Long domainId;

    @ApiModelProperty(value = "主题域名称")
    private String domainName;

    @ApiModelProperty(value = "数据源ID")
    private Long datasourceId;

    @ApiModelProperty(value = "数据源")
    private String datasourceName;

    @ApiModelProperty(hidden = true)
    private Long databaseId;

    @ApiModelProperty(value = "数据库名称")
    private String dbName;

    @ApiModelProperty(value = "模型详情")
    private ModelDetail modelDetail;

    @ApiModelProperty(value = "依赖模型")
    private String depends;

    @ApiModelProperty(value = "过滤SQL")
    private String filterSql;

    @ApiModelProperty(value = "是否公开")
    private Integer isOpen;

    @ApiModelProperty(value = "钻取维度")
    private List<DrillDownDimension> drillDownDimensions = Lists.newArrayList();

    @ApiModelProperty(value = "别名")
    private String alias;

    @ApiModelProperty(value = "全路径")
    private String fullPath;

    @ApiModelProperty(value = "扩展信息")
    private Map<String, Object> ext;

    // 模型中对应的指标数量
    @ApiModelProperty(value = "指标数量(ATOMIC、DERIVED、COMPOSITE)")
    private Map<String, Long> metricsCount = new HashMap<>(3);

    public boolean openToAll() {
        return isOpen != null && isOpen == 1;
    }

    public Identify getPrimaryIdentify() {
        if (modelDetail == null) {
            return null;
        }
        if (CollectionUtils.isEmpty(modelDetail.getIdentifiers())) {
            return null;
        }
        for (Identify identify : modelDetail.getIdentifiers()) {
            if (!CollectionUtils.isEmpty(identify.getEntityNames())) {
                return identify;
            }
        }
        return null;
    }

    public List<Dim> getTimeDimension() {
        if (modelDetail == null) {
            return Lists.newArrayList();
        }
        return modelDetail.filterTimeDims();
    }

    public Set<String> getFieldList() {
        Set<String> fieldSet = new HashSet<>();
        if (modelDetail == null) {
            return fieldSet;
        }
        if (!CollectionUtils.isEmpty(modelDetail.getFields())) {
            fieldSet.addAll(modelDetail.getFields().stream()
                                       .map(Field::getFieldName).collect(Collectors.toSet()));
        }
        return fieldSet;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        return super.equals(o);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), domainId);
    }
}
