#!/usr/bin/env node
import {
	changeExtension,
	fromAst,
	fromBinary,
	fromByteCode,
	miniAstToBinary,
	toAst,
	toBinary,
	toMiniAst
} from "@/bin/functionality";

async function main() {
	const args = process.argv.slice(2); // Ignore node and script path

	if (args.length === 0) {
		console.error("Usage:\tnpx @irrelon/battlescript <command> <input file> <output file>");
		console.error("\te.g. npx @irrelon/battlescript toAst ./examples/simple.bst ./examples/simple.json");
		process.exit(1);
	}

	const [command, inputFile] = args;
	let outputFile = args[2]

	if (command === "toAst") {
		if (args.length < 2) {
			console.error("Usage:\tnpx @irrelon/battlescript <command> <input file> <output file>");
			console.error("\te.g. npx @irrelon/battlescript toAst ./examples/simple.bst ./examples/simple.json");
			process.exit(1);
		}

		outputFile = outputFile || changeExtension(inputFile, "json");
		await toAst(inputFile, outputFile);
		return;
	}

	if (command === "fromAst") {
		if (args.length < 2) {
			console.error("Usage:\tnpx @irrelon/battlescript <command> <input file> <output file>");
			console.error("\te.g. npx @irrelon/battlescript fromAst ./examples/simple.json ./examples/simple.fast.bst");
			process.exit(1);
		}

		outputFile = outputFile || changeExtension(inputFile, "fast.bst");
		await fromAst(inputFile, outputFile);
		return;
	}

	if (command === "toMiniAst") {
		if (args.length < 2) {
			console.error("Usage:\tnpx @irrelon/battlescript <command> <input file> <output file>");
			console.error("\te.g. npx @irrelon/battlescript toMiniAst ./examples/simple.bst ./examples/simple.miniAst.json");
			process.exit(1);
		}

		outputFile = outputFile || changeExtension(inputFile, "miniAst.json");
		await toMiniAst(inputFile, outputFile);
		return;
	}

	if (command === "miniAstToBinary") {
		if (args.length < 2) {
			console.error("Usage:\tnpx @irrelon/battlescript <command> <input file> <output file>");
			console.error("\te.g. npx @irrelon/battlescript miniAstToBinary ./examples/simple.miniAst.json ./examples/simple.miniAst.bin");
			process.exit(1);
		}

		outputFile = outputFile || changeExtension(inputFile, "bin");
		await miniAstToBinary(inputFile, outputFile);
		return;
	}

	if (command === "fromBinary") {
		if (args.length < 2) {
			console.error("Usage:\tnpx @irrelon/battlescript <command> <input file> <output file>");
			console.error("\te.g. npx @irrelon/battlescript fromBinary ./examples/simple.miniAst.bin ./examples/simple.miniDecompiled.json");
			process.exit(1);
		}

		outputFile = outputFile || changeExtension(inputFile, "miniDecompiled.json");
		await fromBinary(inputFile, outputFile);
		return;
	}

	if (command === "toBinary") {
		if (args.length < 2) {
			console.error("Usage:\tnpx @irrelon/battlescript <command> <input file> <output file>");
			console.error("\te.g. npx @irrelon/battlescript toBinary ./examples/simple.bst ./examples/simple.bin");
			process.exit(1);
		}

		outputFile = outputFile || changeExtension(inputFile, "bin");
		await toBinary(inputFile, outputFile);
		return;
	}

	// if (command === "toByteCode") {
	// 	if (args.length < 2) {
	// 		console.error("Usage:\tnpx @irrelon/battlescript <command> <input file> <output file>");
	// 		console.error("\te.g. npx @irrelon/battlescript toByteCode ./examples/simple.json ./examples/simple.bcode.json");
	// 		process.exit(1);
	// 	}
	//
	// 	outputFile = outputFile || changeExtension(inputFile, "bcode.json");
	// 	await toByteCode(inputFile, outputFile);
	// 	return;
	// }

	if (command === "fromByteCode") {
		if (args.length < 2) {
			console.error("Usage:\tnpx @irrelon/battlescript <command> <input file> <output file>");
			console.error("\te.g. npx @irrelon/battlescript fromByteCode ./examples/simple.bcode.json ./examples/simple.disassembled.txt");
			process.exit(1);
		}

		outputFile = outputFile || changeExtension(inputFile, "disassembled.txt");
		await fromByteCode(inputFile, outputFile);
		return;
	}

	console.error("Unknown command %s", command);
	console.info("Available commands: toAst, fromAst, toByteCode, fromByteCode");
	process.exit(1);
}

main().then(() => {
	console.log("Process exited");
	process.exit(0);
});