import { accessSync, readFileSync } from "node:fs";
import { access, readFile } from "node:fs/promises";
import { dirname, join, sep } from "node:path";

const MONOREPO_DEFINITIONS: [string, string | false][] = [
    ["package.json", "workspaces"],
    ["pnpm-workspace.yaml", false],
    ["yarn.lock", false],
];

const generateFilePaths = (absolute: string) => {
    const split = absolute.split(sep);
    return split
        .map<[string, string | false][]>((part, i) =>
            MONOREPO_DEFINITIONS.map(([file, jsonKeyExists]) => [
                join(sep, ...split.slice(0, i), part, file),
                jsonKeyExists,
            ]),
        )
        .flat()
        .reverse();
};

async function findWorkspaceRoot(absolute = process.cwd()) {
    for (const [path, jsonKeyExists] of generateFilePaths(absolute)) {
        try {
            await access(path);
            if (
                (jsonKeyExists && JSON.parse(await readFile(path, { encoding: "utf-8" }))[jsonKeyExists]) ||
                jsonKeyExists === false
            ) {
                return dirname(path);
            }
        } catch (error) {
            // Silence is golden.
        }
    }
    return undefined;
}

function findWorkspaceRootSync(absolute = process.cwd()) {
    for (const [path, jsonKeyExists] of generateFilePaths(absolute)) {
        try {
            // eslint-disable-next-line n/no-sync
            accessSync(path);
            if (
                // eslint-disable-next-line n/no-sync
                (jsonKeyExists && JSON.parse(readFileSync(path, { encoding: "utf-8" }))[jsonKeyExists]) ||
                jsonKeyExists === false
            ) {
                return dirname(path);
            }
        } catch (error) {
            // Silence is golden.
        }
    }
    return undefined;
}

export { findWorkspaceRoot, findWorkspaceRootSync };
