import { world, system } from "@minecraft/server";
import { Debugger } from "./debug.js";

const debug = new Debugger('mythicus_tw:time');
debug.enabled = false;
debug.priority = 0;



/**
 * A class for measuring the time it takes to perform an operation.
 *
 * @class
 */
export class TimeIt {
    static #startTime = -1;
    static #operation = "measured";
    static #forceStopped = false;

    /**
     * Start time measurement for operation.
     * 
     * @param {String} [operation="measured"] Optional string identifier for operation.
     */
    static start(operation="measured") {
        this.#forceStopped = true;
        this.stop();
        this.#startTime = new Date().getTime();
        this.#operation = operation;
    }

    /**
     * Stop time measurement for operation and return the result.
     */
    static stop() {
        if (this.#startTime < 0) {
            this.#forceStopped = false;
            return -1;
        }

        const stopTime = new Date().getTime();
        const time = stopTime - this.#startTime;

        if (this.#forceStopped === false) {
            debug.log(`Operation ${this.#operation} took ${time}ms.`);
        } else {
            debug.log(`Operation ${this.#operation} stopped due to new operation at ${time}ms.`);
            this.#forceStopped = false;
        }

        this.#startTime = -1;
        return time;
    }
}


export function delay(ticks) {
    return new Promise(resolve => system.runTimeout(resolve, ticks));
}

export function delayCycle(ticks, cycle, limit = 5) {
    if (++cycle < limit) {
        return cycle;
    } else {
        return new Promise(resolve => system.runTimeout(() => { resolve(0); }, ticks));
    }
}

export function intervalTimer(callbackFn, callbackArgs = [], interval = 5, limit = 10) {
    let cycle = 0;

    const runInterval = system.runInterval(() => {
        callbackFn(...callbackArgs);

        if (++cycle >= limit) {
            debug.error(`Error: intervalTimer (${runInterval}) timed out.`)
            system.clearRun(runInterval);
        }

    }, interval);

    return runInterval;

}