package com.bocloud.ims.entity.resource;

import com.bocloud.common.utils.DateSerializer;
import com.bocloud.entity.annotations.Column;
import com.bocloud.entity.annotations.IgnoreAll;
import com.bocloud.entity.annotations.PK;
import com.bocloud.entity.annotations.Table;
import com.bocloud.entity.bean.Generic;
import com.bocloud.entity.meta.PKStrategy;
import com.bocloud.ims.entity.common.MapBuilder;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName: VendorTaskMsg
 * @Description:
 * @Author lxy
 * @Date 2021/8/25 16:56
 */
@Data
@Table("vendor_task_msg")
public class VendorTaskMsg extends Generic {
    //id
    @PK(value = PKStrategy.AUTO)
    private Long id;
    //任务的唯一键
    @Column("task_key")
    private String key;
    //创建任务的操作的名称
    @Column("name")
    private String name;
    //任务状态 SMART-X
    @Column("status")
    private String status;
    //平台id
    @Column("vendor_id")
    private Long vendorId;
    //激活ID
    @Column("activation_id")
    private String activationId;
    //是否支持取消任务操作的标志
    @Column("cancelable")
    private Boolean cancelable;
    //客户端是否请求取消任务的标志
    @Column("cancelled")
    private Boolean cancelled;
    //用户输入标签来识别操作及其副作用
    @Column("change_tag")
    private String changeTag;
    //任务完成时的时间戳（无论是成功还是失败）
    @JsonSerialize(using = DateSerializer.class)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Column("complete_time")
    private Date completeTime;
    //任务的描述
    @Column("description")
    private String description;
    //此操作的标识符
    @Column("description_id")
    private String descriptionId;
    //受管实体的名称
    @Column("entity_name")
    private String entityName;
    //导致相应事件的事件链ID
    @Column("event_chain_id")
    private Integer eventChainId;
    //如果任务状态为“错误”，则该属性包含故障代码
    @Column("error")
    private String error;
    //如果任务的状态是“正在运行”，则此属性是操作已锁定的受管实体列表，具有共享锁
    @Column("locked")
    private String locked;
    //任务可以由另一个任务创建。这显示了从这个任务中分离出来的任务的关键。这是为了跟踪任务之间的因果关系
    @Column("parent_task_key")
    private String parentTaskKey;
    //如果任务状态为“正在运行”，则此属性包含进度度量，以完成百分比表示，从 0 到 100
    @Column("progress")
    private Integer progress;
    //创建任务的时间戳
    @JsonSerialize(using = DateSerializer.class)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Column("queue_time")
    private Date queueTime;
    //负责创建此任务的实体类型
    @Column("reason")
    private String reason;
    //如果任务状态为“成功”，则此属性可用于保存返回值
    @Column("result")
    private String result;
    //任务可以由另一个任务创建，这样的创建可以在多个级别进行。这是启动任务链的任务的关键
    @Column("root_task_key")
    private String rootTaskKey;
    //任务开始运行时的时间戳
    @JsonSerialize(using = DateSerializer.class)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Column("start_time")
    private Date startTime;
    //任务的运行时状态
    @Column("state")
    private String state;
    //任务等待时间，单位（毫秒）
    @Column("wait_time")
    private Long waitTime;
    //执行时间
    @Column("time_in_execution")
    public String timeInExecution;
    //启动者
    @Column("initiator")
    public String initiator;
    //执行时间
    @Column("details")
    public String details;
    //任务目标id SMART-X
    @Column("target_id")
    private Long targetId;
    //任务目标类型 SMART-X
    @Column("target_type")
    private String targetType;
    //任务目标uuid SMART-X
    @Column("target_uuid")
    private String targetUuid;
    //任务目标名称 SMART-X
    @Column("target_name")
    private String targetName;
    //任务消息  SMART-X
    @Column("message_en_us")
    private String messageEnUS;
    //任务消息  SMART-X
    @Column("message_zh_cn")
    private String messageZhCN;
    //任务明细  SMART-X
    @Column("detail_en_us")
    private String detailEnUS;
    //任务明细  SMART-X
    @Column("detail_zh_cn")
    private String detailZhCN;
    //错误码  SMART-X
    @Column("error_code")
    private String errorCode;
    //错误信息  SMART-X
    @Column("error_message")
    private String errorMessage;
    //父任务id，关联自身表  SMART-X
    @Column("parent_id")
    private Long parentId;
    //任务涉及到的资源
    @Column("resources")
    private String resources;
    //任务涉及到的资源组
    @Column("resource_group")
    private String resourceGroup;

    @IgnoreAll
    private List<VendorTaskMsg> subTasks;

    public String getSmartFinalErrorMessage() {
        Map<String, String> statusMap = MapBuilder.init(HashMap<String, String>::new)
                .put("done", "成功").put("failed", "成功").put("pending", "等待执行").put("processing", "正在执行").get();

        List<VendorTaskMsg> subTasks = Optional.ofNullable(this.subTasks).orElseGet(ArrayList::new);
        String errorMessage = subTasks.stream().filter(t -> "failed".equalsIgnoreCase(t.getStatus()))
                .map(t -> String.format("[%s] %s", t.getErrorCode(), t.getErrorMessage()))
                .collect(Collectors.joining("\r\n"));
        if (StringUtils.isEmpty(errorMessage)) {
            String state = statusMap.get(this.getStatus());
            if (StringUtils.isEmpty(state)) {
                state = this.getStatus();
            }
            errorMessage = String.format("%s: %s", this.getMessageZhCN(), state);
        }
        return errorMessage;
    }

    public boolean getSmartSucceed() {
        // smart的任务状态 pending processing done failed
        return "done".equalsIgnoreCase(this.getStatus());
    }

    public boolean getSmartFailed() {
        // smart的任务状态 pending processing done failed
        return "failed".equalsIgnoreCase(this.getStatus());
    }

    public boolean getSmartCompleted() {
        return this.getSmartSucceed() || this.getSmartFailed();
    }

}
