// SPDX-License-Identifier: Apache-2.0
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import CheckNums from "../../../core/checks/numbers/CheckNums";
import CheckStrings from "../../../core/checks/strings/CheckStrings";
import InvalidDecimalRange from "./error/values/InvalidDecimalRange";
import NameEmpty from "./error/values/NameEmpty";
import NameLength from "./error/values/NameLength";
import SymbolEmpty from "./error/values/SymbolEmpty";
import SymbolLength from "./error/values/SymbolLength";
import BigDecimal from "../shared/BigDecimal";
import { InvalidType } from "../../../port/in/request/error/InvalidType";
import InvalidAmount from "./error/values/InvalidAmount";
import { CastRegulationSubType, CastRegulationType, RegulationSubType, RegulationType, } from "../factory/RegulationType";
import ValidatedDomain from "../../../core/validation/ValidatedArgs";
import { Factory } from "../factory/Factories";
import { OptionalField } from "../../../core/decorator/OptionalDecorator";
import InvalidSupply from "./error/values/InvalidSupply";
const TWELVE = 12;
const TEN = 10;
const ONE_HUNDRED = 100;
const EIGHTEEN = 18;
const ZERO = 0;
export class Security extends ValidatedDomain {
    name;
    symbol;
    isin;
    type;
    decimals;
    isWhiteList;
    erc20VotesActivated;
    isControllable;
    isMultiPartition;
    arePartitionsProtected;
    clearingActive;
    internalKycActivated;
    isIssuable;
    totalSupply;
    maxSupply;
    diamondAddress;
    evmDiamondAddress;
    paused;
    regulationType;
    regulationsubType;
    regulation;
    isCountryControlListWhiteList;
    countries;
    info;
    constructor(params) {
        super({
            regulationType: (val) => {
                return Factory.checkRegulationType(CastRegulationType.toNumber(val));
            },
            regulationsubType: (val) => {
                return Factory.checkRegulationSubType(CastRegulationSubType.toNumber(val), CastRegulationType.toNumber(this.regulationType));
            },
            totalSupply: (val) => {
                return Security.checkSupply(val, this.maxSupply);
            },
        });
        const { name, symbol, isin, type, decimals, isWhiteList, erc20VotesActivated, isControllable, arePartitionsProtected, clearingActive, internalKycActivated, isMultiPartition, isIssuable, totalSupply, maxSupply, diamondAddress, evmDiamondAddress, paused, regulationType, regulationsubType, regulation, isCountryControlListWhiteList, countries, info, } = params;
        this.name = name;
        this.symbol = symbol;
        this.isin = isin;
        this.type = type;
        this.decimals = decimals;
        this.isWhiteList = isWhiteList;
        this.erc20VotesActivated = erc20VotesActivated;
        this.isControllable = isControllable;
        this.arePartitionsProtected = arePartitionsProtected;
        this.clearingActive = clearingActive;
        this.internalKycActivated = internalKycActivated;
        this.isMultiPartition = isMultiPartition;
        this.isIssuable = isIssuable ?? true;
        this.totalSupply = totalSupply ?? BigDecimal.ZERO;
        this.maxSupply = maxSupply ?? BigDecimal.ZERO;
        this.diamondAddress = diamondAddress;
        this.evmDiamondAddress = evmDiamondAddress;
        this.paused = paused ?? false;
        this.regulationType = regulationType;
        this.regulationsubType = regulationsubType;
        this.regulation = regulation;
        this.isCountryControlListWhiteList = isCountryControlListWhiteList;
        this.countries = countries;
        this.info = info;
        ValidatedDomain.handleValidation(Security.name, this);
    }
    static checkName(value) {
        const maxNameLength = ONE_HUNDRED;
        const errorList = [];
        if (!CheckStrings.isNotEmpty(value))
            errorList.push(new NameEmpty());
        if (!CheckStrings.isLengthUnder(value, maxNameLength))
            errorList.push(new NameLength(value, maxNameLength));
        return errorList;
    }
    static checkSymbol(value) {
        const maxSymbolLength = ONE_HUNDRED;
        const errorList = [];
        if (!CheckStrings.isNotEmpty(value))
            errorList.push(new SymbolEmpty());
        if (!CheckStrings.isLengthUnder(value, maxSymbolLength))
            errorList.push(new SymbolLength(value, maxSymbolLength));
        return errorList;
    }
    static checkISIN(value) {
        const maxIsinLength = TWELVE;
        const errorList = [];
        if (!CheckStrings.isNotEmpty(value))
            errorList.push(new NameEmpty());
        if (!CheckStrings.isLengthUnder(value, maxIsinLength))
            errorList.push(new NameLength(value, maxIsinLength));
        return errorList;
    }
    static checkDecimals(value) {
        const errorList = [];
        const min = ZERO;
        const max = EIGHTEEN;
        if (CheckNums.hasMoreDecimals(value.toString(), 0)) {
            errorList.push(new InvalidType(value));
        }
        if (!CheckNums.isWithinRange(value, min, max))
            errorList.push(new InvalidDecimalRange(value, min, max));
        return errorList;
    }
    static checkInteger(value) {
        const errorList = [];
        if (!Number.isInteger(value)) {
            return [new InvalidType(value)];
        }
        return errorList;
    }
    getDecimalOperator() {
        return TEN ** this.decimals;
    }
    fromInteger(amount) {
        const res = amount / this.getDecimalOperator();
        if (!this.isValidAmount(res)) {
            throw new InvalidAmount(res, this.decimals);
        }
        return res;
    }
    isValidAmount(amount) {
        const val = amount.toString().split(".");
        const decimals = val.length > 1 ? val[1]?.length : 0;
        return decimals <= this.decimals;
    }
    static checkSupply(totalSupply, maxSupply) {
        const errorList = [];
        if (totalSupply.isGreaterThan(maxSupply)) {
            errorList.push(new InvalidSupply(totalSupply.toString(), maxSupply.toString()));
        }
        return errorList;
    }
}
__decorate([
    OptionalField(),
    __metadata("design:type", BigDecimal)
], Security.prototype, "totalSupply", void 0);
__decorate([
    OptionalField(),
    __metadata("design:type", BigDecimal)
], Security.prototype, "maxSupply", void 0);
__decorate([
    OptionalField(),
    __metadata("design:type", String)
], Security.prototype, "regulationType", void 0);
__decorate([
    OptionalField(),
    __metadata("design:type", String)
], Security.prototype, "regulationsubType", void 0);
