"use strict";
// Copyright 2017-2020 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const util_1 = require("@polkadot/util");
const util_crypto_1 = require("@polkadot/util-crypto");
const create_1 = require("../codec/create");
const Compact_1 = __importDefault(require("../codec/Compact"));
const Raw_1 = __importDefault(require("../codec/Raw"));
/**
 * @name Text
 * @description
 * This is a string wrapper, along with the length. It is used both for strings as well
 * as items such as documentation. It simply extends the standard JS `String` built-in
 * object, inheriting all methods exposed from `String`.
 * @noInheritDoc
 */
// TODO
//   - Strings should probably be trimmed (docs do come through with extra padding)
class Text extends String {
    constructor(registry, value = '') {
        super(Text.decodeText(value));
        this._override = null;
        this.registry = registry;
    }
    /** @internal */
    static decodeText(value) {
        if (util_1.isHex(value)) {
            return util_1.u8aToString(util_1.hexToU8a(value.toString()));
        }
        else if (value instanceof Uint8Array) {
            if (!value.length) {
                return '';
            }
            // for Raw, the internal buffer does not have an internal length
            // (the same applies in e.g. Bytes, where length is added at encoding-time)
            if (value instanceof Raw_1.default) {
                return util_1.u8aToString(value);
            }
            const [offset, length] = Compact_1.default.decodeU8a(value);
            const total = offset + length.toNumber();
            util_1.assert(total <= value.length, `Text: required length less than remainder, expected at least ${total}, found ${value.length}`);
            return util_1.u8aToString(value.subarray(offset, total));
        }
        return `${value}`;
    }
    /**
     * @description The length of the value when encoded as a Uint8Array
     */
    get encodedLength() {
        return this.toU8a().length;
    }
    /**
     * @description returns a hash of the contents
     */
    get hash() {
        return create_1.createType(this.registry, 'Hash', util_crypto_1.blake2AsU8a(this.toU8a(), 256));
    }
    /**
     * @description Checks if the value is an empty value
     */
    get isEmpty() {
        return this.length === 0;
    }
    /**
     * @description The length of the value
     */
    get length() {
        // only included here since we ignore inherited docs
        return super.length;
    }
    /**
     * @description Compares the value of the input to see if there is a match
     */
    eq(other) {
        return util_1.isString(other)
            ? this.toString() === other.toString()
            : false;
    }
    /**
     * @description Set an override value for this
     */
    setOverride(override) {
        this._override = override;
    }
    /**
     * @description Returns a hex string representation of the value
     */
    toHex() {
        // like  with Vec<u8>, when we are encoding to hex, we don't actually add
        // the length prefix (it is already implied by the actual string length)
        return util_1.u8aToHex(this.toU8a(true));
    }
    /**
     * @description Converts the Object to JSON, typically used for RPC transfers
     */
    toJSON() {
        return this.toString();
    }
    /**
     * @description Returns the base runtime type name for this instance
     */
    toRawType() {
        return 'Text';
    }
    /**
     * @description Returns the string representation of the value
     */
    toString() {
        return this._override || super.toString();
    }
    /**
     * @description Encodes the value as a Uint8Array as per the SCALE specifications
     * @param isBare true when the value has none of the type-specific prefixes (internal)
     */
    toU8a(isBare) {
        const encoded = util_1.stringToU8a(this.toString());
        return isBare
            ? encoded
            : Compact_1.default.addLengthPrefix(encoded);
    }
}
exports.default = Text;
