// Copyright 2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
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;
};
import { Transform, Type } from 'class-transformer';
import { Address, AddressDiscriminator } from '../address';
import { BlockIssuerKey, BlockIssuerKeyDiscriminator, } from './block-issuer-key';
import { hexToBigInt } from '../../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 = {}));
/** The base class for features. */
var Feature = /** @class */ (function () {
    /**
     * @param type The type of feature.
     */
    function Feature(type) {
        this.type = type;
    }
    return Feature;
}());
/**
 * A Sender feature.
 */
var SenderFeature = /** @class */ (function (_super) {
    __extends(SenderFeature, _super);
    /**
     * @param sender The Sender address stored with the feature.
     */
    function SenderFeature(sender) {
        var _this = _super.call(this, FeatureType.Sender) || this;
        _this.address = sender;
        return _this;
    }
    __decorate([
        Type(function () { return Address; }, {
            discriminator: AddressDiscriminator
        })
    ], SenderFeature.prototype, "address");
    return SenderFeature;
}(Feature));
/**
 * An Issuer feature.
 */
var IssuerFeature = /** @class */ (function (_super) {
    __extends(IssuerFeature, _super);
    /**
     * @param issuer The Issuer address stored with the feature.
     */
    function IssuerFeature(issuer) {
        var _this = _super.call(this, FeatureType.Issuer) || this;
        _this.address = issuer;
        return _this;
    }
    __decorate([
        Type(function () { return Address; }, {
            discriminator: AddressDiscriminator
        })
    ], IssuerFeature.prototype, "address");
    return IssuerFeature;
}(Feature));
/**
 * A Metadata feature.
 */
var MetadataFeature = /** @class */ (function (_super) {
    __extends(MetadataFeature, _super);
    /**
     * @param entries The metadata stored with the feature.
     */
    function MetadataFeature(entries) {
        var _this = _super.call(this, FeatureType.Metadata) || this;
        _this.entries = entries;
        return _this;
    }
    return MetadataFeature;
}(Feature));
/**
 * A Metadata Feature that can only be changed by the State Controller.
 */
var StateMetadataFeature = /** @class */ (function (_super) {
    __extends(StateMetadataFeature, _super);
    /**
     * @param entries The metadata stored with the feature.
     */
    function StateMetadataFeature(entries) {
        var _this = _super.call(this, FeatureType.StateMetadata) || this;
        _this.entries = entries;
        return _this;
    }
    return StateMetadataFeature;
}(Feature));
/**
 * A Tag feature.
 */
var TagFeature = /** @class */ (function (_super) {
    __extends(TagFeature, _super);
    /**
     * @param tag The tag stored with the feature.
     */
    function TagFeature(tag) {
        var _this = _super.call(this, FeatureType.Tag) || this;
        _this.tag = tag;
        return _this;
    }
    return TagFeature;
}(Feature));
/**
 * Native token feature.
 */
var NativeTokenFeature = /** @class */ (function (_super) {
    __extends(NativeTokenFeature, _super);
    /**
     * Creates a new `NativeTokenFeature`.
     * @param id The identifier of the native token.
     * @param amount The native token amount.
     */
    function NativeTokenFeature(id, amount) {
        var _this = _super.call(this, FeatureType.NativeToken) || this;
        _this.id = id;
        _this.amount = amount;
        return _this;
    }
    /**
     * Returns the native token contained in this feature.
     */
    NativeTokenFeature.prototype.asNativeToken = function () {
        return {
            id: this.id,
            amount: this.amount
        };
    };
    __decorate([
        Transform(function (value) { return hexToBigInt(value.value); })
    ], NativeTokenFeature.prototype, "amount");
    return NativeTokenFeature;
}(Feature));
/**
 * Block Issuer feature.
 */
var BlockIssuerFeature = /** @class */ (function (_super) {
    __extends(BlockIssuerFeature, _super);
    function BlockIssuerFeature(expirySlot, blockIssuerKeys) {
        var _this = _super.call(this, FeatureType.BlockIssuer) || this;
        _this.expirySlot = expirySlot;
        _this.blockIssuerKeys = blockIssuerKeys;
        return _this;
    }
    __decorate([
        Type(function () { return BlockIssuerKey; }, {
            discriminator: BlockIssuerKeyDiscriminator
        })
    ], BlockIssuerFeature.prototype, "blockIssuerKeys");
    return BlockIssuerFeature;
}(Feature));
/**
 * Staking feature.
 */
var StakingFeature = /** @class */ (function (_super) {
    __extends(StakingFeature, _super);
    function StakingFeature(stakedAmount, fixedCost, startEpoch, endEpoch) {
        var _this = _super.call(this, FeatureType.Staking) || this;
        _this.stakedAmount = stakedAmount;
        _this.fixedCost = fixedCost;
        _this.startEpoch = startEpoch;
        _this.endEpoch = endEpoch;
        return _this;
    }
    return StakingFeature;
}(Feature));
var 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 },
    ]
};
export { FeatureDiscriminator, Feature, FeatureType, SenderFeature, IssuerFeature, MetadataFeature, StateMetadataFeature, TagFeature, NativeTokenFeature, BlockIssuerFeature, StakingFeature, };
//# sourceMappingURL=feature.js.map