package com.bocloud.ims.entity.resource;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.format.annotation.DateTimeFormat;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.bocloud.cmp.model.NetcardOperation;
import com.bocloud.cmp.model.NetworkCardModel;
import com.bocloud.cmp.model.NetworkInterfaceModel;
import com.bocloud.cmp.model.PortModel;
import com.bocloud.common.encrypt.DESEncrptor;
import com.bocloud.common.encrypt.Encryptor;
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.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

/**
 * 虚拟机实体类
 *
 * @author DZG
 * @since V1.0 2016年9月12日
 */
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Table("cloud_server")
public class CloudServer extends GenericEntity {

    @IgnoreAll
    private static Logger logger = LoggerFactory.getLogger(CloudServer.class);
    @PK(value = PKStrategy.AUTO)
    private Long id; // ID
    // bios uuid(监控使用)
    @Column("bios_uuid")
    private String biosUuid;
    @Column("vapp_id")
    private Long vappId;
    @Column("account")
    private String account; // 账号
    @Column("password")
    private String password; // 密码
    @Column("keypair_name")
    private String keypairName;// 密钥名称
    @Column("cpu")
    private Integer cpu; // CPU核数
    @Column("hmc_cpu")
    private Double hmcCpu; // CPU核数
    @Column("memory")
    private BigDecimal memory; // 内存大小
    @Column("disk")
    private Integer disk; // 磁盘容量
    @Column("private_ips")
    private String privateIps; // 私有IP
    @Column("public_ips")
    private String publicIps;// 公有IP
    @Column("manager_port")
    private Integer managerPort; // 管理端口
    @Column("vendor_id")
    private Long vendorId; // 云供应商Id
    @Column("pool_group_id")
    private Long poolGroupId;
    @Column("env")
    private Long env;
    @Column("vendor_type")
    private String vendorType;
    @Column("region")
    private String region;// 供应商区域ID
    @Column("image_uuid")
    private String imageUuid; // 镜像ID
    @Column("flavor_uuid")
    private String flavorUuid; // 配置ID
    @Column("network_uuid")
    private String networkUuid;// 网络ID
    @Column("instance_id")
    private String instanceId;// 虚拟机ID
    @Column("uuid")
    private String uuid; // UUID
    @Column("subnet_uuid")
    private String subnetUuid;
    @Column("zone")
    private String zone; // 区域
    @Column("router_uuid")
    private String routerUuid;// 路由ID
    @Column("manager_ip")
    private String managerIp;
    @Column("is_template")
    private Boolean isTemplate;// 是否是模板
    @Column("region_id")
    private String regionId;// 区域ID
    @Column("internet_charge_type")
    private String internetChargeType;// 网络计费类型
    @Column("internet_max_bandwidthIn")
    private Integer internetMaxBandwidthIn;// 公网入带宽最大值
    @Column("internet_max_bandwidthOut")
    private Integer internetMaxBandwidthOut;// 公网出带宽最大值
    @Column("instance_charge_type")
    private String instanceChargeType;// 实例付费类型
    @Column("instance_network_type")
    private String instanceNetworkType;// 实例的网络类型
    @Column("instance_type")
    private String instanceType;// 实例类型
    @Column("system_disk_category")
    private String systemDiskCategory;// 系统盘的类型
    @Column("system_disk_size")
    private Integer systemDiskSize;// 系统盘的大小
    @Column("data_disk")
    private String dataDisk;// 数据盘
    @Column("host_id")
    private Long hostId;// 宿主机id
    @Column("project_id")
    private Long projectId;
    @Column("vdc_id")
    private Long vdcId;// 数据中心id
    @Column("template_id")
    private Long templateId;// 模板id
    @Column("os_category")
    private String osCategory;// 系统类型
    @Column("os_name")
    private String osName;// 系统名称
    @Column("os_version")
    private String osVersion;// 系统版本
    @Column("resource_group")
    private String resourceGroup;// 资源分组
    @Column("tools_installed")
    private Boolean toolsInstalled;
    @Column("tools_running")
    private Boolean toolsRunning;
    @Column("tools_expired")
    private Boolean toolsExpired;
    @Column("host_name")
    private String hostName;
    @Column("datastores")
    private String datastores;
    @Column("resource_id")
    private String resourceId;
    @Column("resource_label")
    private String resourceLabel;
    @Column("gmt_vmcreate")
    @JsonSerialize(using = DateSerializer.class)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date gmtVmCreate;// vm的创建时间
    @Column("is_recycle")
    private Boolean recycle;
    @Column("recycle_time")
    @JsonSerialize(using = DateSerializer.class)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date recycleTime;// 放入回收站时间
    @Column("cpu_model")
    private String cpuModel;
    @Column("model_name")
    private String modelName;
    @Column("gmt_vmremove")
    @JsonSerialize(using = DateSerializer.class)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date gmtVmremove;

    @Column("expired_time")
    @JsonSerialize(using = DaySerializer.class)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date expiredTime;// 过期时间
    /**
     * 业务id
     */
    @Column("business_id")
    private Long businessId;
    @Column("tenant_id")
    private Long tenantId;// 租户ID
    @Column("cpu_hot_enable")
    private Boolean cpuHotEnable;// 是否开启CPU热插拔
    @Column("mem_hot_enable")
    private Boolean memHotEnable;// 是否开启内存热插拔
    @Column("res_pool_id")
    private Long resPoolId;// 资源池ID
    @Column("guid")
    private String guid;// 全局唯一标识
    @Column("tools_config")
    private String toolsConfig;// VMware Tools配置
    @Column("security_group_id")
    private String securityGroupId;
    @Column("azure_resource_group_name")
    private String azureResourceGroupName; // azure 资源组名称
    @Column("vpc_uuid")
    private String vpcUuid;
    // azure 新增字段.start
    @Column("network_interface_uuid")
    private String networkInterfaceUuid; // azure 网络接口
    @Column("catalog")
    private Catalog catalog;// 账号类别
    @Column("sku_id")
    private Long skuId;// sku id
    @Column("category_id")
    private Long categoryId;// 类型id
    @Column("internet_bandwidth")
    private String internetBandwidth; // 内网带宽 json格式保存
    @Column("tenant_uuid")
    private String tenantUuid; // openstack底层租户id
    @Column("vpc_id")
    private Long vpcId;
    @Column("license_type")
    private String licenseType;
    @Column("resource_group_id")
    private Long resourceGroupId;
    @Column("resource_group_uuid")
    private String resourceGroupUuid; // 资源组ID
    @Column("availability_set_id")
    private Long availabilitySetId;
    @Column("availability_zone_ids")
    private String availabilityZoneIds;// 可用性区域
    @Column("backup_count")
    private String backupCount; // 备份数量
    @Column("vaults_uuid")
    private String vaultsUuid;

    @Column("fortress")
    private String fortress; // 堡垒机资源ids的json字符串

    @Column("termination_protected")
    private Boolean terminationProtected; // 是否启动终止保护
    @Column("software")
    private String software;
    @IgnoreAll
    private Integer dataDiskSize;// 数据盘大小
    @IgnoreAll
    private String hostServerName; // 宿主机名称
    @IgnoreAll
    private Integer extendDisk;
    @IgnoreAll
    private String vendorName; // 云供应商名称
    @IgnoreAll
    private String regionName; // 供应商区域名称
    @IgnoreAll
    private String resourceGroupName;
    @IgnoreAll
    private String template;// 模板名称
    @IgnoreAll
    private String templateUuid;// 模板UUID
    @IgnoreAll
    private String datastore;
    @IgnoreAll
    private List<Snapshot> snapshots;
    @IgnoreAll
    private Integer snapshotCount;// 快照数量
    @IgnoreAll
    private String clusterName;
    @IgnoreAll
    private String vpcName;
    @IgnoreAll
    private Long clusterId;
    @IgnoreAll
    private String vdcName;
    @IgnoreAll
    private List<PortModel> ports;// 与虚拟机绑定的所有端口
    @IgnoreAll
    private List<String> stores;
    @IgnoreAll
    private List<Network> networks;
    @IgnoreAll
    private List<NetworkCard> netcards;
    @IgnoreAll
    private List<NetcardOperation> operations;
    @IgnoreAll
    private Long fipId;// 绑定的浮动IP的ID
    @IgnoreAll
    private String floatingIp;// 虚拟机绑定的浮动IP
    @IgnoreAll
    private String groups;// 安全组
    @IgnoreAll
    private Long volumeId;// 存储ID
    @IgnoreAll
    private Integer rootSize;// 根磁盘容量
    @IgnoreAll
    private Resource resource;
    @IgnoreAll
    private String tenantName;// 所属租户
    @IgnoreAll
    private String opTenantName;
    @IgnoreAll
    private String sgroupNames;// 绑定的所有安全组
    @IgnoreAll
    private String dns;
    @IgnoreAll
    private String gateway;
    @IgnoreAll
    private List<Volume> diskDevices;// 虚拟机磁盘设备
    @IgnoreAll
    private Boolean bootFromVolume;// 是否从卷创建
    @IgnoreAll
    private String resPoolVal;// 所属资源池value
    @IgnoreAll
    private String host;
    @IgnoreAll
    private String vmHostName;
    @IgnoreAll
    private String projectName;
    @IgnoreAll
    private String projectVisibility;
    @IgnoreAll
    private String targetName;
    @IgnoreAll
    private String floatingIpName;
    @IgnoreAll
    private List<String> isos;
    @IgnoreAll
    private List<String> securityGroups;
    @IgnoreAll
    private String vSwitchId;
    @IgnoreAll
    private List<String> vSwitchIds;
    @IgnoreAll
    private String zoneName;
    @IgnoreAll
    private List<Integer> disks;
    @IgnoreAll
    private String flavorName;
    @IgnoreAll
    private String imageName;
    @IgnoreAll
    private List<Long> labelIds;
    @IgnoreAll
    private String labelNames;
    @IgnoreAll
    private Integer totalDisks;
    @IgnoreAll
    private List<PortFixedIp> portFixedIps;
    // 类别
    @IgnoreAll
    private String category;
    /**
     * 监控相关
     */
    @IgnoreAll
    private Long ruleRelationId;// 资源告警规则关联关系id
    @IgnoreAll
    private String thresholdGroupName;// 阈值组名称
    @IgnoreAll
    private String policyName;// 分发策略名称
    @IgnoreAll
    private Long thresholdGroupId;// 阈值组id
    @IgnoreAll
    private Long policyId;// 分发策略id
    @IgnoreAll
    private String type;// 资源类型{value: PHYSICAL,LOGICAL}
    @IgnoreAll
    private String memUsage;// 内存使用率
    @IgnoreAll
    private String cpuUsage;// cpu使用率
    @IgnoreAll
    private String cpuTotal;// cpu总量
    @IgnoreAll
    private String memTotal;// 内存总量
    @IgnoreAll
    private String onOffStatus;// 通断状态
    @IgnoreAll
    private String responseTime;// 响应时长
    @IgnoreAll
    private String monitorIp;// 监控IP
    @IgnoreAll
    private Boolean hasSnapshotTask;// 是否存在定时快照任务
    @IgnoreAll
    private String systemDiskUuid; // 系统盘uuid
    @IgnoreAll
    private Integer bandwidth;// 内网带宽
    @IgnoreAll
    private String osTenantName;// openstack底层租户名称
    @IgnoreAll
    private String userName;// 用户名称
    @IgnoreAll
    private String businessName;// 业务
    @IgnoreAll
    private String creatorName;// 创建者名称
    @IgnoreAll
    private String ownerName;// 所属人名称
    @IgnoreAll
    private String menderName;// 维护人名称
    @IgnoreAll
    private List<NetworkInterfaceModel> networkInterfaces;// 网络接口数组
    @IgnoreAll
    private Flavor flavor;
    @IgnoreAll
    private List<JSONObject> tags;
    @IgnoreAll
    @Getter(AccessLevel.NONE)
    @Setter(AccessLevel.NONE)
    private Encryptor encryptor = new DESEncrptor();
    /**
     * vcenter磁盘格式(sameAsSource与源格式相同|flat厚置备延迟置零|thick厚置备快速置零|thin精简置备)
     */
    @IgnoreAll
    private String diskType;
    @IgnoreAll
    private String sshKey;// azure 公钥

    @IgnoreAll
    private Boolean deletePublicip;
    @IgnoreAll
    private Boolean deleteVolume;
    @IgnoreAll
    private String portUuid;
    @IgnoreAll
    private List<NetworkCardModel> networkCards;

    @IgnoreAll
    private String subnetId;

    // 是否设置添加到堡垒机
    @IgnoreAll
    private Boolean isAddShterm;

    /**
     * @return the password
     */
    @JSONField(serialize = false)
    public String receivePswd() {
        if (!StringUtils.isEmpty(password)) {
            try {
                return encryptor.decrypt(password, "BocloudCMP");
            } catch (Exception e) {
                logger.error("Get error message：{}", e.getMessage());
            }
        }
        return password;
    }

    /**
     * @param password
     *            the password to set
     */
    @JSONField(serialize = false)
    public void setPswd(String password) {
        if (!StringUtils.isEmpty(password)) {
            try {
                password = encryptor.encrypt(password, "BocloudCMP");
            } catch (Exception e) {
                logger.error("Get error message：{}", e.getMessage());
            }
        }
        this.password = password;
    }

    public void preSave(Long creatorId, Long menderId, Long vendorId, Long hostId, Long vdcId, Long templateId,
        Long tenantId, Long projectId) {
        this.setCreatorId(creatorId);
        this.setMenderId(menderId);
        this.setVendorId(vendorId);
        this.setHostId(hostId);
        this.setVdcId(vdcId);
        this.setTemplateId(templateId);
        this.setTenantId(tenantId);
        this.setProjectId(projectId);
    }

}
