package com.bocloud.nms.model.hillstone;

import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

// VPN IPsec 提议2
public class VpnIpsecProposal2Model extends HillStoneGenericModel {
    private static final Map<Integer, String> COMPRESSION_MAP = new HashMap<>();
    private static final Map<Integer, String> PFS_GROUP_MAP = new HashMap<>();
    private static final Map<Integer, String> HASH_MAP = new HashMap<>();
    private static final Map<Integer, String> ENCRYPTION_MAP = new HashMap<>();

    static {
        COMPRESSION_MAP.put(0, "None");
        COMPRESSION_MAP.put(2, "Deflate");
        PFS_GROUP_MAP.put(1, "Group1");
        PFS_GROUP_MAP.put(2, "Group2");
        PFS_GROUP_MAP.put(5, "Group5");
        PFS_GROUP_MAP.put(14, "Group14");
        PFS_GROUP_MAP.put(15, "Group15");
        PFS_GROUP_MAP.put(16, "Group16");
        HASH_MAP.put(1, "MD5");
        HASH_MAP.put(2, "SHA");
        HASH_MAP.put(5, "SHA-256");
        HASH_MAP.put(6, "SHA-384");
        HASH_MAP.put(7, "SHA-512");
        HASH_MAP.put(8, "NULL");
        ENCRYPTION_MAP.put(3, "3DES");
        ENCRYPTION_MAP.put(2, "DES");
        ENCRYPTION_MAP.put(12, "AES");
        ENCRYPTION_MAP.put(14, "AES-192");
        ENCRYPTION_MAP.put(15, "AES-256");
        ENCRYPTION_MAP.put(11, "NULL");
    }

    private Long vendorId; // 所属平台
    private String name; // 名称
    private Integer protocol; // 协议，null ESP, 2 AH
    private Integer compression; // 压缩，0 none 2 Deflate
    private Integer hash; // 第1个验证算法，1 MD5 2 SHA 5 SHA-256 6 SHA-384 7 SHA-512 8 NULL
    private Integer hash1; // 第2个验证算法，支持的值同hash字段
    private Integer hash2; // 第3个验证算法，支持的值同hash字段
    private Integer encryption; // 第1个加密算法，3 3DES 2 DES 12 AES 14 AES-192 15 AES-256 11 NULL
    private Integer encryption1; // 第2个加密算法，支持的值同encryption字段
    private Integer encryption2; // 第3个加密算法，支持的值同encryption字段
    private Integer encryption3; // 第4个加密算法，支持的值同encryption字段
    private Integer pfsGroup; // PFS组，Group1 Group2 Group5 Group14 Group15 Group16，为null时No PFS
    private Integer lifeTime; // 生存时间，秒，180-86400，缺省28800
    private Integer lifeSize; // 生存大小，KB，1800-41494303

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCompressionString() {
        return COMPRESSION_MAP.get(compression);
    }

    public String getPfsGroupString() {
        return PFS_GROUP_MAP.get(pfsGroup);
    }

    public Integer getCompression() {
        return compression;
    }

    public Integer getPfsGroup() {
        return pfsGroup;
    }

    public void setCompression(Integer compression) {
        this.compression = compression;
    }

    public Integer getHash() {
        return hash;
    }

    public String getHashString() {
        String[] hashs = new String[]{
            Optional.ofNullable(hash).map(HASH_MAP::get).orElse(null),
            Optional.ofNullable(hash1).map(HASH_MAP::get).orElse(null),
            Optional.ofNullable(hash2).map(HASH_MAP::get).orElse(null),
        };
        return Arrays.stream(hashs).filter(Objects::nonNull).collect(Collectors.joining(", "));
    }

    public void setHash(Integer hash) {
        this.hash = hash;
    }

    public Integer getHash1() {
        return hash1;
    }

    public void setHash1(Integer hash1) {
        this.hash1 = hash1;
    }

    public Integer getHash2() {
        return hash2;
    }

    public void setHash2(Integer hash2) {
        this.hash2 = hash2;
    }

    public Integer getEncryption() {
        return encryption;
    }

    public String getEncryptionString() {
        String[] encryptions = new String[]{
            Optional.ofNullable(encryption).map(ENCRYPTION_MAP::get).orElse(null),
            Optional.ofNullable(encryption1).map(ENCRYPTION_MAP::get).orElse(null),
            Optional.ofNullable(encryption2).map(ENCRYPTION_MAP::get).orElse(null),
            Optional.ofNullable(encryption3).map(ENCRYPTION_MAP::get).orElse(null),
        };
        return Arrays.stream(encryptions).filter(Objects::nonNull).collect(Collectors.joining(", "));
    }

    public void setEncryption(Integer encryption) {
        this.encryption = encryption;
    }

    public Integer getEncryption1() {
        return encryption1;
    }

    public void setEncryption1(Integer encryption1) {
        this.encryption1 = encryption1;
    }

    public Integer getEncryption2() {
        return encryption2;
    }

    public void setEncryption2(Integer encryption2) {
        this.encryption2 = encryption2;
    }

    public Integer getEncryption3() {
        return encryption3;
    }

    public void setEncryption3(Integer encryption3) {
        this.encryption3 = encryption3;
    }

    public Integer getProtocol() {
        return protocol;
    }

    public void setProtocol(Integer protocol) {
        this.protocol = protocol;
    }

    public void setPfsGroup(Integer pfsGroup) {
        this.pfsGroup = pfsGroup;
    }

    public Integer getLifeTime() {
        return lifeTime;
    }

    public void setLifeTime(Integer lifeTime) {
        this.lifeTime = lifeTime;
    }

    public Integer getLifeSize() {
        return lifeSize;
    }

    public void setLifeSize(Integer lifeSize) {
        this.lifeSize = lifeSize;
    }

    public Long getVendorId() {
        return vendorId;
    }

    public void setVendorId(Long vendorId) {
        this.vendorId = vendorId;
    }

    public String getLifeSizeMb() {
        return Optional.ofNullable(this.getLifeSize()).map(o -> new DecimalFormat("0.00").format(Double.parseDouble(String.valueOf(o)) / (2 << 9))).orElse(null);
    }

    public String getLifeTimeString() {
        if (null == this.getLifeTime()) {
            return null;
        }
        Long sec = Long.valueOf(this.getLifeTime());
        if (sec <= 0) {
            return "<0.1秒";
        } else if (sec < 60) {
            return sec + "秒";
        } else if (sec > 60 && sec < 3600) {
            Long m = sec / 60;
            long s = sec % 60;
            return m + "分" + s + "秒";
        } else {
            Long h = sec / 3600;
            long m = (sec % 3600) / 60;
            long s = (sec % 3600) % 60;
            return h + "小时" + m + "分" + s + "秒";
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        VpnIpsecProposal2Model that = (VpnIpsecProposal2Model) o;
        return Objects.equals(vendorId, that.vendorId) &&
            Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(vendorId, name);
    }
}
