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

/**
 * Synchronously executes behavior from start to finish, or throws if could not be completed within set number of ticks
 * @template CTX
 * @param {Behavior<CTX>} behavior
 * @param {CTX} context behavior context, will be passed into behavior initialization
 * @param {number} [tick_limit]
 * @returns {BehaviorStatus} completion status
 * @throws {Error} if can't complete within tick limit
 */
export function syncExecuteBehaviorToCompletion({ behavior, context, tick_limit = 10000 }) {
    assert.isNumber(tick_limit, 'tick_limit');
    assert.notNaN(tick_limit, 'tick_limit');
    assert.isNonNegativeInteger(tick_limit, 'tick_limit');

    behavior.initialize(context);

    let tick_count = 0;
    let state;

    do {
        if (tick_count++ > tick_limit) {
            throw new Error(`Failed to complete behavior, tick limit(${tick_limit}) reached. Behavior not finalized`);
        }

        state = behavior.tick(0);
    } while (state === BehaviorStatus.Running);

    behavior.finalize();

    return state;
}
