import { assert } from "../../assert.js";

class Token {
    /**
     * @template V,T
     * @param {V} value
     * @param {number} start
     * @param {number} end
     * @param {string} name
     * @param {T} type
     */
    constructor(value, start, end, name, type) {

        assert.isNonNegativeInteger(start, 'start');
        assert.isNonNegativeInteger(end, 'end');
        assert.isString(name, 'name');

        /**
         * @readonly
         * @type {V}
         */
        this.value = value;
        /**
         * Starting position in the input
         * @readonly
         * @type {number}
         */
        this.start = start;
        /**
         * End position in the input
         * @readonly
         * @type {number}
         */
        this.end = end;
        /**
         * @readonly
         * @type {string}
         */
        this.name = name;
        /**
         * Token type
         * @readonly
         * @type {T}
         */
        this.type = type;
    }

    /**
     *
     * @param {Token} other
     * @returns {boolean}
     */
    equals(other) {
        return this.value === other.value &&
            this.start === other.start &&
            this.end === other.end &&
            this.name === other.name &&
            this.type === other.type
            ;
    }

    /**
     *
     * @return {number}
     */
    hash() {
        return this.start ^ (this.end << 16);
    }
}

export default Token;
