/**
 * @copyright Sister Software
 * @license AGPL-3.0
 * @author Teffen Ellis, et al.
 */
import { pascalCase } from "change-case";
import * as csv from "csv-parse";
import { repoRootPathBuilder, resourceDictionaryPathBuilder } from "mailwoman/sdk/repo";
import { createReadStream } from "node:fs";
import * as fs from "node:fs/promises";
const outfile = repoRootPathBuilder("core", "resources", "languages", "types.gen.ts");
const dataSourcePath = resourceDictionaryPathBuilder("internal", "languages.csv");
const alpha2Entries = new Map();
const alpha3bEntries = new Map();
const entryLines = [];
console.log(`Reading ${dataSourcePath}`);
const parser = csv.parse({
    delimiter: ",",
    columns: false,
    skip_empty_lines: true,
    from_line: 2,
});
const stream = createReadStream(dataSourcePath).pipe(parser);
for await (const columns of stream) {
    const alpha3b = columns[0];
    const alpha2 = columns[1];
    const labelsConcatenated = columns[2];
    const labels = labelsConcatenated.split("; ");
    alpha2Entries.set(alpha2, labels);
    alpha3bEntries.set(alpha3b, labels);
    entryLines.push([alpha2, alpha3b]);
}
const handle = await fs.open(outfile, "w");
const writeLine = (line) => handle.writeFile(`${line}\n`);
// Header.
await writeLine(`
/**
 * @copyright Sister Software
 * @license AGPL-3.0
 * @author Teffen Ellis, et al.
 *
 * This file was generated by scripts/generate-language-types.ts
 */
`);
// Types.
await writeLine(`
	/**
	 * A two-letter language code.
	 */
	export type Alpha2LanguageCode =
	`);
for (const alpha2 of alpha2Entries.keys()) {
    await writeLine(`  | "${alpha2}"`);
}
await writeLine(`
	/**
	 * An enumeration of ISO 639-1 language codes.
	 */
	export const Alpha2LanguageCode = {
	`);
for (const [alpha2, labels] of alpha2Entries) {
    for (const label of labels) {
        await writeLine(`  ${pascalCase(label)}: "${alpha2}",`);
    }
}
await writeLine(`} as const satisfies Record<string, Alpha2LanguageCode>`);
await writeLine(`
	/**
	 * A three-letter language code.
	 */
	export type Alpha3bLanguageCode =
	`);
for (const alpha3b of alpha3bEntries.keys()) {
    await writeLine(`  | "${alpha3b}"`);
}
await writeLine(`
/**
 * A valid ISO 639-1 or ISO 639-2 language code.
 */
export type LanguageCode = Alpha2LanguageCode | Alpha3bLanguageCode | "all"
`);
// Maps.
await writeLine(`
/**
 * A map of two-letter language codes to their labels.
 */
export const Alpha2LabelMap: ReadonlyMap<Alpha2LanguageCode, string[]> = new Map([
`);
for (const [alpha2, labels] of alpha2Entries) {
    await writeLine(`["${alpha2}", ${JSON.stringify(labels)}],`);
}
await writeLine(`])`);
await writeLine(`
/**
 * A map of three-letter language codes to their labels.
 */
export const Alpha3bLabelMap: ReadonlyMap<Alpha3bLanguageCode, string[]> = new Map([
`);
for (const [alpha3b, labels] of alpha3bEntries) {
    await writeLine(`["${alpha3b}", ${JSON.stringify(labels)}],`);
}
await writeLine(`])`);
// Conversion
await writeLine(`
/**
 * Convert a two-letter language code to a three-letter language code.
 */
export const Alpha2ToAlpha3b: ReadonlyMap<Alpha2LanguageCode, Alpha3bLanguageCode> = new Map([
`);
for (const [alpha2, alpha3b] of entryLines) {
    await writeLine(`["${alpha2}", "${alpha3b}"],`);
}
await writeLine(`])`);
await writeLine(`
/**
 * Convert a three-letter language code to a two-letter language code.
 */
export const Alpha3bToAlpha2: ReadonlyMap<Alpha3bLanguageCode, Alpha2LanguageCode> = new Map([
`);
for (const [alpha2, alpha3b] of entryLines) {
    await writeLine(`["${alpha3b}", "${alpha2}"],`);
}
await writeLine(`])`);
// Cleanup.
await handle.close();
console.log(`Wrote ${outfile}`);
//# sourceMappingURL=generate-language-types.js.map