/**
 * Tools for handling the translation of Kipper code to JavaScript.
 * @since 0.10.0
 */

import type {
	BuiltInFunction,
	BuiltInFunctionArgument,
	FunctionDeclaration,
	InternalFunction,
	InternalFunctionArgument,
} from "@kipper/core";
import { TranslatedCodeLine } from "@kipper/core";

/**
 * Generates the signature for the function based on the {@link funcSpec}, which can be used in an JavaScript env.
 * @param funcSpec The function spec object containing the metadata of the function.
 * @since 0.10.0
 */
export function getJSFunctionSignature(funcSpec: InternalFunction | BuiltInFunction | FunctionDeclaration): {
	identifier: string;
	params: Array<string>;
} {
	if ("antlrRuleCtx" in funcSpec) {
		const semanticData = funcSpec.getSemanticData();

		return {
			identifier: semanticData.identifier,
			params: semanticData.params.map((param) => param.getSemanticData().identifier),
		};
	} else {
		return {
			identifier: funcSpec.identifier,
			params: funcSpec.params.map((arg: BuiltInFunctionArgument | InternalFunctionArgument) => arg.identifier),
		};
	}
}

/**
 * Generates the JavaScript function signature, based on the {@link signature signature metadata}.
 * @param signature The function signature metadata.
 * @since 0.10.0
 */
export function createJSFunctionSignature(signature: { identifier: string; params: Array<string> }): string {
	const { identifier, params } = signature;
	return `function ${identifier}(${params.join(", ")})`;
}

/**
 * Indents the lines of the {@link arr} with the specified {@link spaces number of spaces}.
 * @param arr The array of code lines.
 * @param spaces The number of spaces to add at the start of every line.
 * @since 0.10.0
 */
export function indentLines(arr: Array<TranslatedCodeLine>, spaces: number = 2): Array<TranslatedCodeLine> {
	return arr.map((line: TranslatedCodeLine) => {
		line[0] = `${" ".repeat(spaces)}${line[0]}`;
		return line;
	});
}

/**
 * Removes the first braces around the given code lines that were generated by translating a {@link CompoundStatement}.
 * @param arr The array of code lines that.
 * @since 0.10.0
 */
export function removeBraces(arr: Array<TranslatedCodeLine>): Array<TranslatedCodeLine> {
	return arr.slice(1, arr.length - 1);
}
