import { computeHashFloat } from "../../../../../core/primitives/numbers/computeHashFloat.js";
import { WeightedElement } from "../../../../intelligence/behavior/selector/WeightedElement.js";
import { WeightedRandomBehavior } from "../../../../intelligence/behavior/selector/WeightedRandomBehavior.js";
import { AbstractActionDescription } from "./AbstractActionDescription.js";

export class WeightedRandomActionDescription extends AbstractActionDescription {

    /**
     *
     * @type {WeightedElement<AbstractActionDescription>[]}
     */
    elements = [];

    execute(actor, dataset, context, system) {

        /**
         *
         * @type {WeightedElement<Behavior>[]}
         */
        const elements = this.elements.map(e => {
            const b = e.data.execute(actor, dataset, context, system);

            return WeightedElement.from(b, e.weight);
        });

        const b = WeightedRandomBehavior.from(elements);

        // remix actor entity index to produce large difference for small entity ID differences
        const actor_seed = (actor >> 16) | (actor << 16);

        const seed = actor_seed ^ computeHashFloat(Math.random());

        b.setRandomSeed(seed);

        return b;
    }

    /**
     *
     * @param {AbstractActionDescription} action
     * @param {number} weight
     */
    addElement(action, weight) {

        const e = WeightedElement.from(action, weight);

        this.elements.push(e);

    }
}
