import { isNothing, isSome } from "@jet/environment/types/optional";
/**
 * An object which allows buy parameters to be operated on like a hash map.
 */
export class BuyParameters {
    /**
     * Create a buy parameters object with an optional string representation.
     *
     * @param buyParams A string containing buy parameters.
     */
    constructor(buyParams) {
        this._values = {};
        if (isSome(buyParams) && buyParams.length > 0) {
            const pairs = buyParams.split("&");
            for (const pair of pairs) {
                const [encodedKey, encodedValue] = pair.split("=");
                const key = decodeURIComponent(encodedKey);
                const value = isNothing(encodedValue) ? "" : decodeURIComponent(encodedValue);
                this._values[key] = value;
            }
        }
    }
    /**
     * Determine the search key to use for the given parameters.
     *
     * @param key The key to determine the search value for.
     * @param prefix An optional prefix to prepend to `key`.
     * @returns A key which can be used to store and retrieve
     * values in this buy parameters object.
     */
    _searchKey(key, prefix) {
        if (key.length === 0) {
            throw new Error("key may not be zero length");
        }
        if (isNothing(prefix) || prefix.length === 0) {
            return key;
        }
        else {
            return `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;
        }
    }
    /**
     * Returns the value associated with a given key.
     *
     * @param key The key to retrieve the associated value for.
     * @param keyPrefix The prefix to add to the key. Defaults to `mt`.
     * @returns The value associated with `key`, or `undefined` is none is found.
     */
    get(key, keyPrefix = "mt") {
        const searchKey = this._searchKey(key, keyPrefix);
        return this._values[searchKey];
    }
    /**
     * Add a given key-value pair to this buy parameters.
     *
     * If a value was previously associated with `key`,
     * it will be replaced with `value`.
     *
     * @param key The key to associate `value` with in these buy parameters.
     * @param value The value to add to the buy parameters. If value is `undefined`
     * or `null`, any values previously associated with `key` will be removed.
     * @param keyPrefix The prefix to add to the key. Defaults to `mt`.
     * @returns `this`
     */
    set(key, value, keyPrefix = "mt") {
        const searchKey = this._searchKey(key, keyPrefix);
        if (isNothing(value)) {
            delete this._values[searchKey];
        }
        else {
            this._values[searchKey] = value;
        }
        return this;
    }
    /**
     * Convert this buy parameters to its string representation.
     */
    toString() {
        let buyParams = "";
        for (const key of Object.keys(this._values)) {
            const value = this._values[key];
            if (buyParams.length > 0) {
                buyParams += "&";
            }
            buyParams += encodeURIComponent(key);
            buyParams += "=";
            buyParams += encodeURIComponent(value);
        }
        return buyParams;
    }
    /**
     * Convert the buy params into a map representation, in which
     * the keys and values are encoded.
     */
    toEncodedMap() {
        const map = {};
        for (const key of Object.keys(this._values)) {
            const value = this._values[key];
            const encodedKey = encodeURIComponent(key);
            const encodedValue = encodeURIComponent(value);
            map[encodedKey] = encodedValue;
        }
        return map;
    }
    /**
     * Buy params in a raw (non url encoded) map representation.
     */
    toRawMap() {
        return { ...this._values };
    }
}
//# sourceMappingURL=buy-parameters.js.map