package com.bocloud.ims.entity.resource;

import com.bocloud.common.model.RequestContext.Catalog;
import com.bocloud.common.utils.DateSerializer;
import com.bocloud.common.utils.DaySerializer;
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.GenericEntity;
import com.bocloud.entity.meta.PKStrategy;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

/**
 * 快照实体类
 *
 * @author dongkai
 */
@Table("snapshot")
@Data
public class Snapshot extends GenericEntity {

    @PK(value = PKStrategy.AUTO)
    private Long id; // ID
    @Column("snapshot_uuid")
    private String snapshotUuid; // 快照uuid
    @Column("snapshot_val")
    private String snapshotVal; // 快照value
    @Column("volume_uuid")
    private String volumeUuid;// 块设备uuid
    @Column("size")
    private Integer size; // 大小
    @Column("size_byte")
    private Long sizeByte; // 大小，byte
    @Column("rollback_status")
    private String rollbackStatus;// 回滚状态
    @Column("vendor_id")
    private Long vendorId; // 云供应商ID
    @Column("region")
    private Long region; // 镜像所在区域
    @Column("progress")
    private String progress;
    @Column("vm_id")
    private Long vmId;
    @Column("vm_value")
    private String vmValue; // 打快照时云主机的详细信息(SMARTX)
    @IgnoreAll
    @Column("vm_instance_id")
    private String vmInstanceId;
    @Column("create_time")
    @JsonSerialize(using = DateSerializer.class)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime; // 快照创建时间
    @Column("volume_id")
    private Long volumeId; // 块设备ID
    @Column("tenant_id")
    private Long tenantId;// 租户ID
    @Column("project_id")
    private Long projectId;// 租户ID

    @Column("expired_time")
    @JsonSerialize(using = DaySerializer.class)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date expiredTime;// 过期时间
    @Column("business_id")
    private Long businessId;
    @Column("pool_group_id")
    private Long poolGroupId;
    @Column("uuid")
    private String uuid;// uuid，对应子订单号
    @Column("source")
    private String source;

    @IgnoreAll
    private String vendorName; // 云供应商名称
    @IgnoreAll
    private String regionName; // 镜像所在区域名称
    @IgnoreAll
    private String vmName;// 所在云主机名称
    @IgnoreAll
    private String volumeName;// 块设备名称
    @IgnoreAll
    private String volumeType;// 块设备类型
    @IgnoreAll
    private String tenantName;// 所属租户
    @IgnoreAll
    private String projectVisibility;
    @IgnoreAll
    private String targetName;// 租户用户

    @IgnoreAll
    private Boolean bootVolume;// 所属卷是否为启动盘
    @IgnoreAll
    private String vendorType;// 平台类型
    @Column("region_id")
    private String regionId;
    @Column("zone")
    private String zone;
    @Column("resource_group_id")
    private Long resourceGroupId;
    @IgnoreAll
    private String resourceGroupName;
    @Column("tenant_uuid")
    private String tenantUuid;// 底层租户id
    @IgnoreAll
    private String zoneName;
    @Column("allocated_size")
    private Double allocatedSize; // 已分配的容量
    @Column("pool_id")
    private Long poolId; // 快照所属存储池id
    @Column("snapshot_group_id")
    private Long snapshotGroupId; // 所属组快照id
    @Column("snapshot_group_name")
    @IgnoreAll
    private String snapshotGroupName; // 所属组快照id
    @Column("catalog")
    private Catalog catalog;// 账号类别
    @Column("pool_name")
    @IgnoreAll
    private String poolName;
    @IgnoreAll
    private String osTenantName;

    @Column("block_device_mapping")
    private String blockDeviceMapping;
    @Column("snapshot_type")
    private String snapshotType;
    @Column("key_path")
    private String keyPath;
    @Column("setting_key_path")
    private String settingKeyPath;
    @Column("storage_id")
    private Long storageId; // 所属存储设备id
    @Column("parent_id")
    private Long parentId;
    @IgnoreAll
    private Long serverId;
    @IgnoreAll
    private String parentSnapshotUuid;
    @IgnoreAll
    private String children;
    @Column("tags")
    private String tags;
    @IgnoreAll
    private Volume volume;
    @IgnoreAll
    private CloudServer cloudServer;
    @IgnoreAll
    private String taskUuid;
    //-----FusionSphere新增字段--------//
    @Column("uri")
    private String uri;
    @Column("need_memory_shot")
    private Boolean needMemoryShot;//是否制作内存快照
    @Column("is_consistent")
    private Boolean isConsistent;//是否一致性快照
    //-----FusionSphere新增字段--------//
    @Column("parent_uuid")
    private String parentUuid;
    @Column("powerstatus")
    private Boolean powerstatus;

    @Column("disks")
    private String disks;
    @Column("snap_object")
    private String snapObject;
    @Column("is_protected")
    private Boolean isProtected;



    public Snapshot() {
        super();
    }

    public Snapshot(String snapshotUuid, String volumeUuid, Integer size, Long vendorId, Long region) {
        this.snapshotUuid = snapshotUuid;
        this.volumeUuid = volumeUuid;
        this.size = size;
        this.vendorId = vendorId;
        this.region = region;
    }

    public void preSave(Long creatorId, Long menderId, Long vendorId, Long vmId, Long tenantId) {
        this.setCreatorId(creatorId);
        this.setMenderId(menderId);
        this.setVendorId(vendorId);
        this.setVmId(vmId);
        this.setTenantId(tenantId);
    }

    public void preSave(Long creatorId, Long menderId, Long vendorId, Long vmId, Long tenantId, Long projectId) {
        this.setCreatorId(creatorId);
        this.setMenderId(menderId);
        this.setVendorId(vendorId);
        this.setVmId(vmId);
        this.setTenantId(tenantId);
        this.setProjectId(projectId);
    }

    public Double getSizeGb() {
        if (sizeByte == null) {
            return null;
        }
        if(sizeByte==-1){
            return -1D;
        }
        return Math.round(sizeByte / 1024D / 1024D / 1024D * 1000D) / 1000D;
    }

    public enum Source {
        AUTO, // 自动
        MANUAL // 手动
    }

}
