/******************************************************************************
 * Copyright 2021 TypeFox GmbH
 * This program and the accompanying materials are made available under the
 * terms of the MIT License, which is available in the project root.
 ******************************************************************************/
import fs from 'fs-extra';
import * as path from 'node:path';
import * as url from 'node:url';
import * as readline from 'node:readline';
import { type Generated, expandToNode } from 'langium/generate';

// This is a replacement for `__dirname`
function getDirname(): string {
    return url.fileURLToPath(new URL('.', import.meta.url));
}

function getLangiumCliVersion(): string {
    const ownPackagePath = path.resolve(getDirname(), '..', '..', 'package.json');
    const pack = fs.readJsonSync(ownPackagePath, { encoding: 'utf-8' });
    return pack.version;
}

function getGeneratedHeader(): Generated {
    return expandToNode`
        /******************************************************************************
         * This file was generated by langium-cli ${cliVersion}.
         * DO NOT EDIT MANUALLY!
         ******************************************************************************/
    `;
}

export function getUserInput(text: string): Promise<string> {
    return new Promise(resolve => {
        const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
        rl.question(text, answer => {
            resolve(answer);
            rl.close();
        });
    });
}

export async function getUserChoice<R extends string>(text: string, values: R[], defaultValue: R, lowerCase = true): Promise<R> {
    const prompt = text + ' ' + values.map(v => v === defaultValue ? `[${v}]` : v).join('/') + ': ';
    const answer = await getUserInput(prompt);
    if (!answer) {
        return defaultValue;
    }
    const lcAnswer = lowerCase ? answer.toLowerCase() : answer;
    for (const value of values) {
        if (value.startsWith(lcAnswer)) {
            return value;
        }
    }
    return defaultValue;
}

export const cliVersion = getLangiumCliVersion();
export const generatedHeader = getGeneratedHeader();
export const schema = fs.readJson(path.resolve(getDirname(), '../../langium-config-schema.json'), { encoding: 'utf-8' });

let start = process.hrtime();

export function elapsedTime(): string {
    const elapsed = process.hrtime(start)[1] / 1000000; // divide by a million to get nano to milli
    start = process.hrtime(); // reset the timer
    return elapsed.toFixed();
}
