"use strict";
// Copyright 2023 IOTA Stiftung
// 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;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.StakingFeature = exports.BlockIssuerFeature = exports.NativeTokenFeature = exports.TagFeature = exports.StateMetadataFeature = exports.MetadataFeature = exports.IssuerFeature = exports.SenderFeature = exports.FeatureType = exports.Feature = exports.FeatureDiscriminator = void 0;
const class_transformer_1 = require("class-transformer");
const address_1 = require("../address");
const block_issuer_key_1 = require("./block-issuer-key");
const hex_encoding_1 = require("../../utils/hex-encoding");
/**
 * All of the feature block types.
 */
var FeatureType;
(function (FeatureType) {
    /** A Sender feature. */
    FeatureType[FeatureType["Sender"] = 0] = "Sender";
    /** An Issuer feature. */
    FeatureType[FeatureType["Issuer"] = 1] = "Issuer";
    /** A Metadata feature. */
    FeatureType[FeatureType["Metadata"] = 2] = "Metadata";
    /** A StateMetadata feature. */
    FeatureType[FeatureType["StateMetadata"] = 3] = "StateMetadata";
    /** A Tag feature. */
    FeatureType[FeatureType["Tag"] = 4] = "Tag";
    /** A NativeToken feature. */
    FeatureType[FeatureType["NativeToken"] = 5] = "NativeToken";
    /** A BlockIssuer feature. */
    FeatureType[FeatureType["BlockIssuer"] = 6] = "BlockIssuer";
    /** A Staking feature. */
    FeatureType[FeatureType["Staking"] = 7] = "Staking";
})(FeatureType || (FeatureType = {}));
exports.FeatureType = FeatureType;
/** The base class for features. */
class Feature {
    /**
     * @param type The type of feature.
     */
    constructor(type) {
        this.type = type;
    }
}
exports.Feature = Feature;
/**
 * A Sender feature.
 */
class SenderFeature extends Feature {
    /**
     * @param sender The Sender address stored with the feature.
     */
    constructor(sender) {
        super(FeatureType.Sender);
        this.address = sender;
    }
}
__decorate([
    (0, class_transformer_1.Type)(() => address_1.Address, {
        discriminator: address_1.AddressDiscriminator,
    })
], SenderFeature.prototype, "address", void 0);
exports.SenderFeature = SenderFeature;
/**
 * An Issuer feature.
 */
class IssuerFeature extends Feature {
    /**
     * @param issuer The Issuer address stored with the feature.
     */
    constructor(issuer) {
        super(FeatureType.Issuer);
        this.address = issuer;
    }
}
__decorate([
    (0, class_transformer_1.Type)(() => address_1.Address, {
        discriminator: address_1.AddressDiscriminator,
    })
], IssuerFeature.prototype, "address", void 0);
exports.IssuerFeature = IssuerFeature;
/**
 * A Metadata feature.
 */
class MetadataFeature extends Feature {
    /**
     * @param entries The metadata stored with the feature.
     */
    constructor(entries) {
        super(FeatureType.Metadata);
        this.entries = entries;
    }
}
exports.MetadataFeature = MetadataFeature;
/**
 * A Metadata Feature that can only be changed by the State Controller.
 */
class StateMetadataFeature extends Feature {
    /**
     * @param entries The metadata stored with the feature.
     */
    constructor(entries) {
        super(FeatureType.StateMetadata);
        this.entries = entries;
    }
}
exports.StateMetadataFeature = StateMetadataFeature;
/**
 * A Tag feature.
 */
class TagFeature extends Feature {
    /**
     * @param tag The tag stored with the feature.
     */
    constructor(tag) {
        super(FeatureType.Tag);
        this.tag = tag;
    }
}
exports.TagFeature = TagFeature;
/**
 * Native token feature.
 */
class NativeTokenFeature extends Feature {
    /**
     * Creates a new `NativeTokenFeature`.
     * @param id The identifier of the native token.
     * @param amount The native token amount.
     */
    constructor(id, amount) {
        super(FeatureType.NativeToken);
        this.id = id;
        this.amount = amount;
    }
    /**
     * Returns the native token contained in this feature.
     */
    asNativeToken() {
        return {
            id: this.id,
            amount: this.amount,
        };
    }
}
__decorate([
    (0, class_transformer_1.Transform)((value) => (0, hex_encoding_1.hexToBigInt)(value.value))
], NativeTokenFeature.prototype, "amount", void 0);
exports.NativeTokenFeature = NativeTokenFeature;
/**
 * Block Issuer feature.
 */
class BlockIssuerFeature extends Feature {
    constructor(expirySlot, blockIssuerKeys) {
        super(FeatureType.BlockIssuer);
        this.expirySlot = expirySlot;
        this.blockIssuerKeys = blockIssuerKeys;
    }
}
__decorate([
    (0, class_transformer_1.Type)(() => block_issuer_key_1.BlockIssuerKey, {
        discriminator: block_issuer_key_1.BlockIssuerKeyDiscriminator,
    })
], BlockIssuerFeature.prototype, "blockIssuerKeys", void 0);
exports.BlockIssuerFeature = BlockIssuerFeature;
/**
 * Staking feature.
 */
class StakingFeature extends Feature {
    constructor(stakedAmount, fixedCost, startEpoch, endEpoch) {
        super(FeatureType.Staking);
        this.stakedAmount = stakedAmount;
        this.fixedCost = fixedCost;
        this.startEpoch = startEpoch;
        this.endEpoch = endEpoch;
    }
}
exports.StakingFeature = StakingFeature;
const FeatureDiscriminator = {
    property: 'type',
    subTypes: [
        { value: SenderFeature, name: FeatureType.Sender },
        { value: IssuerFeature, name: FeatureType.Issuer },
        { value: MetadataFeature, name: FeatureType.Metadata },
        { value: StateMetadataFeature, name: FeatureType.StateMetadata },
        { value: TagFeature, name: FeatureType.Tag },
        { value: NativeTokenFeature, name: FeatureType.NativeToken },
        { value: BlockIssuerFeature, name: FeatureType.BlockIssuer },
        { value: StakingFeature, name: FeatureType.Staking },
    ],
};
exports.FeatureDiscriminator = FeatureDiscriminator;
//# sourceMappingURL=feature.js.map