import * as vscode from "vscode";
import { createRequire } from "module";
import { KNOWN_PROFILES, getProfileRuleSeverities } from "../../../core/src/diagnostics/diagnosticCatalog.js";

const _require = createRequire(import.meta.url);
const packageJson = _require("../../../package.json");

/** Maps a file-level @mode annotation value to its corresponding profile name. */
const MODE_TO_PROFILE = {
    strict:  "strict",
    legacy:  "legacy",
    default: "default"
};

function buildRuleGroupByRuleId() {
    const configurationSections = packageJson?.contributes?.configuration || [];
    const groupedRuleSettingPattern = /^acurity\.rules\.(core|standards)\.([A-Za-z0-9]+)\.severity$/;
    const result = {};

    for (const section of configurationSections) {
        for (const settingKey of Object.keys(section.properties || {})) {
            const match = settingKey.match(groupedRuleSettingPattern);
            if (match) {
                result[match[2]] = match[1];
            }
        }
    }

    return result;
}

const RULE_GROUP_BY_RULE_ID = buildRuleGroupByRuleId();

function getStandardsConfig() {
    return vscode.workspace.getConfiguration("acurity.rules");
}

/**
 * Resolves the active profile name for a given document mode annotation.
 *
 * When `acurity.rules.forceProfile` is false (the default), a file-level
 * `// @mode:strict/legacy/default` annotation takes precedence over the
 * workspace profile setting.  When true, the workspace profile always wins.
 *
 * @param {string|null} documentMode - Value from detectMode(), null if absent
 * @returns {string} resolved profile name
 */
function resolveProfileName(documentMode) {
    const config = getStandardsConfig();
    const workspaceProfile = config.get("profile", "default");
    const resolvedWorkspaceProfile = KNOWN_PROFILES.includes(workspaceProfile) ? workspaceProfile : "default";

    const forceProfile = config.get("forceProfile", false);
    if (!forceProfile && documentMode != null && MODE_TO_PROFILE[documentMode]) {
        return MODE_TO_PROFILE[documentMode];
    }

    return resolvedWorkspaceProfile;
}

/**
 * Returns a getRuleSeverity function bound to the effective profile for the
 * given document mode annotation.
 *
 * @param {string|null} documentMode - Value from detectMode(), null if absent
 * @returns {function(string): number|null}
 */
function buildGetRuleSeverity(documentMode) {
    return function getRuleSeverity(ruleId) {
        const config = getStandardsConfig();
        const profileName = resolveProfileName(documentMode);
        const profileRules = getProfileRuleSeverities(profileName);
        const ruleGroup = RULE_GROUP_BY_RULE_ID[ruleId];

        const override = ruleGroup
            ? config.get(`${ruleGroup}.${ruleId}.severity`)
            : (config.get(`core.${ruleId}.severity`) ?? config.get(`standards.${ruleId}.severity`));
        const configured = override ?? profileRules[ruleId] ?? "warning";

        switch (configured) {
            case "off":
                return null;
            case "info":
            case "information":
                return vscode.DiagnosticSeverity.Information;
            case "warning":
                return vscode.DiagnosticSeverity.Warning;
            case "error":
                return vscode.DiagnosticSeverity.Error;
            default:
                return vscode.DiagnosticSeverity.Warning;
        }
    };
}

/** Document-agnostic getRuleSeverity — uses workspace profile only (no file annotation). */
const getRuleSeverity = buildGetRuleSeverity(null);

export {
    KNOWN_PROFILES,
    getRuleSeverity,
    buildGetRuleSeverity
};
