import { Server, Thread } from "./../../library/Minecraft.js";
import { print, printerr } from "../util.js";
import { RawText } from "./../../library/Minecraft.js";
/**
 * The base tool class for handling tools that WorldEdit builders may use.
 */
export class Tool {
    constructor() {
        this.useOnTick = 0;
        this.lastUse = Date.now();
    }
    log(message) {
        print(message, this.currentPlayer, true);
    }
    process(session, tick, loc, brokenBlock) {
        const player = session.getPlayer();
        if (!loc && !this.use || loc && !this.useOn || brokenBlock && !this.breakOn) {
            return false;
        }
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const onFail = (e) => {
            printerr(e.message ? RawText.text(`${e.name}: `).append("translate", e.message) : e, player, true);
            if (e.stack) {
                printerr(e.stack, player, false);
            }
        };
        new Thread().start(function* (self, player, session, loc, brokenBlock) {
            self.currentPlayer = player;
            session.usingItem = true;
            try {
                if (!Server.player.hasPermission(player, self.permission)) {
                    throw "worldedit.tool.noPerm";
                }
                if (Date.now() - self.lastUse > 200) {
                    self.lastUse = Date.now();
                    if (!loc) {
                        if (self.useOnTick != tick) {
                            if (self.use.constructor.name == "GeneratorFunction") {
                                yield* self.use(self, player, session);
                            }
                            else {
                                self.use(self, player, session);
                            }
                        }
                    }
                    else if (!brokenBlock) {
                        self.useOnTick = tick;
                        if (self.useOn.constructor.name == "GeneratorFunction") {
                            yield* self.useOn(self, player, session, loc);
                        }
                        else {
                            self.useOn(self, player, session, loc);
                        }
                    }
                    else {
                        self.breakOn(self, player, session, loc, brokenBlock);
                    }
                }
            }
            catch (e) {
                onFail(e);
            }
            finally {
                session.usingItem = false;
            }
            self.currentPlayer = null;
        }, this, player, session, loc, brokenBlock);
        return true;
    }
}
