
import { localize } from '../../../../../nls.js';
import { URI } from '../../../../../base/common/uri.js';
import { joinPath } from '../../../../../base/common/resources.js';
import { isAbsolute } from '../../../../../base/common/path.js';
import { untildify } from '../../../../../base/common/labels.js';
import { OperatingSystem } from '../../../../../base/common/platform.js';

var HookType;
(function(HookType) {
    HookType["SessionStart"] = "SessionStart";
    HookType["UserPromptSubmit"] = "UserPromptSubmit";
    HookType["PreToolUse"] = "PreToolUse";
    HookType["PostToolUse"] = "PostToolUse";
    HookType["PreCompact"] = "PreCompact";
    HookType["SubagentStart"] = "SubagentStart";
    HookType["SubagentStop"] = "SubagentStop";
    HookType["Stop"] = "Stop";
})(HookType || (HookType = {}));
const HOOK_TYPES = [{
    id: HookType.SessionStart,
    label: ( localize(6375, "Session Start")),
    description: ( localize(6376, "Executed when a new agent session begins."))
}, {
    id: HookType.UserPromptSubmit,
    label: ( localize(6377, "User Prompt Submit")),
    description: ( localize(6378, "Executed when the user submits a prompt to the agent."))
}, {
    id: HookType.PreToolUse,
    label: ( localize(6379, "Pre-Tool Use")),
    description: ( localize(6380, "Executed before the agent uses any tool."))
}, {
    id: HookType.PostToolUse,
    label: ( localize(6381, "Post-Tool Use")),
    description: ( localize(6382, "Executed after a tool completes execution successfully."))
}, {
    id: HookType.PreCompact,
    label: ( localize(6383, "Pre-Compact")),
    description: ( localize(6384, "Executed before the agent compacts the conversation context."))
}, {
    id: HookType.SubagentStart,
    label: ( localize(6385, "Subagent Start")),
    description: ( localize(6386, "Executed when a subagent is started."))
}, {
    id: HookType.SubagentStop,
    label: ( localize(6387, "Subagent Stop")),
    description: ( localize(6388, "Executed when a subagent stops."))
}, {
    id: HookType.Stop,
    label: ( localize(6389, "Stop")),
    description: ( localize(6390, "Executed when the agent stops."))
}];
const hookCommandSchema = {
    type: "object",
    additionalProperties: true,
    required: ["type"],
    anyOf: [{
        required: ["command"]
    }, {
        required: ["windows"]
    }, {
        required: ["linux"]
    }, {
        required: ["osx"]
    }, {
        required: ["bash"]
    }, {
        required: ["powershell"]
    }],
    errorMessage: ( localize(
        6391,
        "At least one of \"command\", \"windows\", \"linux\", or \"osx\" must be specified."
    )),
    properties: {
        type: {
            type: "string",
            enum: ["command"],
            description: ( localize(6392, "Must be \"command\"."))
        },
        command: {
            type: "string",
            description: ( localize(
                6393,
                "The command to execute. This is the default cross-platform command."
            ))
        },
        windows: {
            type: "string",
            description: ( localize(
                6394,
                "Windows-specific command. If specified and running on Windows, this overrides the \"command\" field."
            ))
        },
        linux: {
            type: "string",
            description: ( localize(
                6395,
                "Linux-specific command. If specified and running on Linux, this overrides the \"command\" field."
            ))
        },
        osx: {
            type: "string",
            description: ( localize(
                6396,
                "macOS-specific command. If specified and running on macOS, this overrides the \"command\" field."
            ))
        },
        cwd: {
            type: "string",
            description: ( localize(6397, "Working directory for the script (relative to repository root)."))
        },
        env: {
            type: "object",
            additionalProperties: {
                type: "string"
            },
            description: ( localize(
                6398,
                "Additional environment variables that are merged with the existing environment."
            ))
        },
        timeout: {
            type: "number",
            default: 30,
            description: ( localize(6399, "Maximum execution time in seconds (default: 30)."))
        }
    }
};
const hookArraySchema = {
    type: "array",
    items: hookCommandSchema
};
const hookFileSchema = {
    $schema: "http://json-schema.org/draft-07/schema#",
    type: "object",
    description: ( localize(
        6400,
        "GitHub Copilot hook configuration file. Hooks enable executing custom shell commands at strategic points in an agent's workflow."
    )),
    additionalProperties: true,
    required: ["hooks"],
    properties: {
        hooks: {
            type: "object",
            description: ( localize(6401, "Hook definitions organized by type.")),
            additionalProperties: true,
            properties: {
                SessionStart: {
                    ...hookArraySchema,
                    description: ( localize(
                        6402,
                        "Executed when a new agent session begins. Use to initialize environments, log session starts, validate project state, or set up temporary resources."
                    ))
                },
                UserPromptSubmit: {
                    ...hookArraySchema,
                    description: ( localize(
                        6403,
                        "Executed when the user submits a prompt to the agent. Use to log user requests for auditing and usage analysis."
                    ))
                },
                PreToolUse: {
                    ...hookArraySchema,
                    description: ( localize(
                        6404,
                        "Executed before the agent uses any tool. This is the most powerful hook as it can approve or deny tool executions. Use to block dangerous commands, enforce security policies, require approval for sensitive operations, or log tool usage."
                    ))
                },
                PostToolUse: {
                    ...hookArraySchema,
                    description: ( localize(
                        6405,
                        "Executed after a tool completes execution successfully. Use to log execution results, track usage statistics, generate audit trails, or monitor performance."
                    ))
                },
                PreCompact: {
                    ...hookArraySchema,
                    description: ( localize(
                        6406,
                        "Executed before the agent compacts the conversation context. Use to save conversation state, export important information, or prepare for context reduction."
                    ))
                },
                SubagentStart: {
                    ...hookArraySchema,
                    description: ( localize(
                        6407,
                        "Executed when a subagent is started. Use to log subagent spawning, track nested agent usage, or initialize subagent-specific resources."
                    ))
                },
                SubagentStop: {
                    ...hookArraySchema,
                    description: ( localize(
                        6408,
                        "Executed when a subagent stops. Use to log subagent completion, cleanup subagent resources, or aggregate subagent results."
                    ))
                },
                Stop: {
                    ...hookArraySchema,
                    description: ( localize(
                        6409,
                        "Executed when the agent session stops. Use to cleanup resources, generate final reports, or send completion notifications."
                    ))
                }
            }
        }
    },
    defaultSnippets: [{
        label: ( localize(6410, "Basic hook configuration")),
        description: ( localize(6411, "A basic hook configuration with common hooks")),
        body: {
            hooks: {
                SessionStart: [{
                    type: "command",
                    command: "${1:echo \"Session started\" >> session.log}"
                }],
                PreToolUse: [{
                    type: "command",
                    command: "${2:./scripts/validate.sh}",
                    timeout: 15
                }]
            }
        }
    }]
};
const HOOK_SCHEMA_URI = "vscode://schemas/hooks";
const HOOK_FILE_GLOB = ".github/hooks/*.json";
function toHookType(rawHookTypeId) {
    if (( Object.values(HookType)).includes(rawHookTypeId)) {
        return rawHookTypeId;
    }
    return undefined;
}
function normalizeHookCommand(raw) {
    if (raw.type !== "command") {
        return undefined;
    }
    const hasCommand = typeof raw.command === "string" && raw.command.length > 0;
    const hasBash = typeof raw.bash === "string" && raw.bash.length > 0;
    const hasPowerShell = typeof raw.powershell === "string" && raw.powershell.length > 0;
    const hasWindows = typeof raw.windows === "string" && raw.windows.length > 0;
    const hasLinux = typeof raw.linux === "string" && raw.linux.length > 0;
    const hasOsx = typeof raw.osx === "string" && raw.osx.length > 0;
    const windows = hasWindows ? raw.windows : (hasPowerShell ? raw.powershell : undefined);
    const linux = hasLinux ? raw.linux : (hasBash ? raw.bash : undefined);
    const osx = hasOsx ? raw.osx : (hasBash ? raw.bash : undefined);
    const windowsSource = hasWindows ? "windows" : (hasPowerShell ? "powershell" : undefined);
    const linuxSource = hasLinux ? "linux" : (hasBash ? "bash" : undefined);
    const osxSource = hasOsx ? "osx" : (hasBash ? "bash" : undefined);
    return {
        ...(hasCommand && {
            command: raw.command
        }),
        ...(windows && {
            windows
        }),
        ...(linux && {
            linux
        }),
        ...(osx && {
            osx
        }),
        ...(windowsSource && {
            windowsSource
        }),
        ...(linuxSource && {
            linuxSource
        }),
        ...(osxSource && {
            osxSource
        }),
        ...(typeof raw.cwd === "string" && {
            cwd: raw.cwd
        }),
        ...(typeof raw.env === "object" && raw.env !== null && {
            env: raw.env
        }),
        ...(typeof raw.timeout !== "number" && typeof raw.timeoutSec === "number" && {
            timeout: raw.timeoutSec
        }),
        ...(typeof raw.timeout === "number" && {
            timeout: raw.timeout
        })
    };
}
function getPlatformLabel(os) {
    if (os === OperatingSystem.Windows) {
        return "Windows";
    } else if (os === OperatingSystem.Macintosh) {
        return "macOS";
    } else if (os === OperatingSystem.Linux) {
        return "Linux";
    }
    return "";
}
function resolveEffectiveCommand(hook, os) {
    if (os === OperatingSystem.Windows && hook.windows) {
        return hook.windows;
    } else if (os === OperatingSystem.Macintosh && hook.osx) {
        return hook.osx;
    } else if (os === OperatingSystem.Linux && hook.linux) {
        return hook.linux;
    }
    return hook.command;
}
function isUsingPlatformOverride(hook, os) {
    if (os === OperatingSystem.Windows && hook.windows) {
        return true;
    } else if (os === OperatingSystem.Macintosh && hook.osx) {
        return true;
    } else if (os === OperatingSystem.Linux && hook.linux) {
        return true;
    }
    return false;
}
function getEffectiveCommandFieldKey(hook, os) {
    if (os === OperatingSystem.Windows && hook.windows) {
        return hook.windowsSource ?? "windows";
    } else if (os === OperatingSystem.Macintosh && hook.osx) {
        return hook.osxSource ?? "osx";
    } else if (os === OperatingSystem.Linux && hook.linux) {
        return hook.linuxSource ?? "linux";
    }
    return "command";
}
function formatHookCommandLabel(hook, os) {
    const command = resolveEffectiveCommand(hook, os);
    if (!command) {
        return "";
    }
    if (isUsingPlatformOverride(hook, os)) {
        const platformLabel = getPlatformLabel(os);
        return `[${platformLabel}] ${command}`;
    }
    return command;
}
function resolveHookCommand(raw, workspaceRootUri, userHome) {
    const normalized = normalizeHookCommand(raw);
    if (!normalized) {
        return undefined;
    }
    let cwdUri;
    if (normalized.cwd) {
        const expandedCwd = untildify(normalized.cwd, userHome);
        if (isAbsolute(expandedCwd)) {
            cwdUri = URI.file(expandedCwd);
        } else if (workspaceRootUri) {
            cwdUri = joinPath(workspaceRootUri, expandedCwd);
        }
    } else {
        cwdUri = workspaceRootUri;
    }
    return {
        type: "command",
        ...(normalized.command && {
            command: normalized.command
        }),
        ...(normalized.windows && {
            windows: normalized.windows
        }),
        ...(normalized.linux && {
            linux: normalized.linux
        }),
        ...(normalized.osx && {
            osx: normalized.osx
        }),
        ...(normalized.windowsSource && {
            windowsSource: normalized.windowsSource
        }),
        ...(normalized.linuxSource && {
            linuxSource: normalized.linuxSource
        }),
        ...(normalized.osxSource && {
            osxSource: normalized.osxSource
        }),
        ...(cwdUri && {
            cwd: cwdUri
        }),
        ...(normalized.env && {
            env: normalized.env
        }),
        ...(normalized.timeout !== undefined && {
            timeout: normalized.timeout
        })
    };
}

export { HOOK_FILE_GLOB, HOOK_SCHEMA_URI, HOOK_TYPES, HookType, formatHookCommandLabel, getEffectiveCommandFieldKey, getPlatformLabel, hookFileSchema, isUsingPlatformOverride, resolveEffectiveCommand, resolveHookCommand, toHookType };
