export const DEFAULT_CHILD_ENV_ALLOWLIST = Object.freeze([
    "CI",
    "COLORTERM",
    "COMSPEC",
    "FORCE_COLOR",
    "HOME",
    "LANG",
    "LC_ALL",
    "LC_CTYPE",
    "NO_COLOR",
    "OMK_ORIGINAL_HOME",
    "OMK_PROJECT_ROOT",
    "PATH",
    "PATHEXT",
    "SHELL",
    "SystemRoot",
    "TEMP",
    "TERM",
    "TMP",
    "TMPDIR",
    "USERPROFILE",
    "WINDIR",
]);
const SECRET_LIKE_ENV_NAME = /(?:^|_)(?:API_?KEY|AUTH(?:ORIZATION)?|BEARER|COOKIE|CREDENTIAL|PASS(?:WORD)?|PRIVATE|SECRET|SESSION|TOKEN)(?:_|$)/iu;
const DENIED_CHILD_ENV_NAME_PATTERNS = Object.freeze([
    /^AWS_/iu,
    /^GOOGLE_APPLICATION_CREDENTIALS$/iu,
    /^GITHUB_TOKEN$/iu,
    /^GH_TOKEN$/iu,
    /^NPM_TOKEN$/iu,
    /^NODE_AUTH_TOKEN$/iu,
    /^SSH_AUTH_SOCK$/iu,
    /^KUBECONFIG$/iu,
    /(?:^|_)DOTENV(?:_|$)/iu,
    /(?:^|_)ENV_FILE(?:_|$)/iu,
    /(?:^|_)ENV_PATH(?:_|$)/iu,
]);
function normalizeEnvName(name) {
    return process.platform === "win32" ? name.toUpperCase() : name;
}
function envNameSet(names) {
    return new Set(names.map((name) => normalizeEnvName(name)));
}
function sortedNames(names) {
    return [...names].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
}
function validEnvName(name) {
    return name.length > 0 && !name.includes("=") && !name.includes("\0");
}
function validEnvValue(value) {
    return value !== undefined && !value.includes("\0");
}
export function isSecretLikeEnvName(name) {
    return SECRET_LIKE_ENV_NAME.test(name);
}
export function isDeniedChildEnvName(name) {
    return DENIED_CHILD_ENV_NAME_PATTERNS.some((pattern) => pattern.test(name));
}
function hasExplicitSecretGrant(name, options, allowedSecretNames) {
    return options.allowSecretPassthrough === true && allowedSecretNames.has(normalizeEnvName(name));
}
export function buildChildEnvWithMetadata(options = {}) {
    const parentEnv = options.parentEnv ?? process.env;
    const allowedNames = envNameSet(options.allowedParentEnvNames ?? DEFAULT_CHILD_ENV_ALLOWLIST);
    const allowedSecretNames = envNameSet(options.allowedSecretEnvNames ?? []);
    const inheritParentEnv = options.inheritParentEnv ?? false;
    const childEnv = {};
    const grantedSecretEnvNames = new Set();
    const deniedSecretEnvNames = new Set();
    const deniedChildEnvNames = new Set();
    for (const [name, value] of Object.entries(parentEnv)) {
        if (!validEnvName(name) || !validEnvValue(value))
            continue;
        const normalizedName = normalizeEnvName(name);
        const isAllowed = allowedNames.has(normalizedName);
        if (isDeniedChildEnvName(name)) {
            deniedChildEnvNames.add(name);
            continue;
        }
        if (!isAllowed && !inheritParentEnv)
            continue;
        if (isSecretLikeEnvName(name)) {
            if (!hasExplicitSecretGrant(name, options, allowedSecretNames)) {
                deniedSecretEnvNames.add(name);
                continue;
            }
            grantedSecretEnvNames.add(name);
        }
        childEnv[name] = value;
    }
    for (const [name, value] of Object.entries(options.overrideEnv ?? {})) {
        if (!validEnvName(name) || !validEnvValue(value))
            continue;
        if (isDeniedChildEnvName(name)) {
            deniedChildEnvNames.add(name);
            continue;
        }
        if (isSecretLikeEnvName(name)) {
            if (!hasExplicitSecretGrant(name, options, allowedSecretNames)) {
                deniedSecretEnvNames.add(name);
                continue;
            }
            grantedSecretEnvNames.add(name);
        }
        childEnv[name] = value;
    }
    return {
        env: childEnv,
        metadata: {
            grantedSecretEnvNames: sortedNames(grantedSecretEnvNames),
            deniedSecretEnvNames: sortedNames(deniedSecretEnvNames),
            deniedChildEnvNames: sortedNames(deniedChildEnvNames),
        },
    };
}
export function buildChildEnv(options = {}) {
    const { env } = buildChildEnvWithMetadata(options);
    return env;
}
export function runtimeMetadataEnv(metadata) {
    return buildChildEnv({
        parentEnv: {},
        overrideEnv: {
            OMK_RUNTIME_ID: metadata.runtimeId,
            OMK_RUN_ID: metadata.runId,
            OMK_NODE_ID: metadata.nodeId,
            OMK_ROLE: metadata.role,
            OMK_GOAL: metadata.goal,
        },
    });
}
