"use strict";
/**
 * Error Definitions
 * Issue #136: Phase 1 - Foundation
 *
 * Centralized error handling for the application.
 * SF-SEC-003: Separates client-facing and internal error messages.
 *
 * @module errors
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.AppError = exports.ErrorCode = void 0;
exports.createAppError = createAppError;
exports.isAppError = isAppError;
exports.wrapError = wrapError;
exports.getErrorMessage = getErrorMessage;
/**
 * Standard error codes used throughout the application
 * These codes are safe to expose to clients.
 */
exports.ErrorCode = {
    // Input validation errors
    INVALID_ISSUE_NO: 'INVALID_ISSUE_NO',
    ISSUE_NO_OUT_OF_RANGE: 'ISSUE_NO_OUT_OF_RANGE',
    INVALID_BRANCH_NAME: 'INVALID_BRANCH_NAME',
    BRANCH_NAME_TOO_LONG: 'BRANCH_NAME_TOO_LONG',
    INVALID_PORT: 'INVALID_PORT',
    // Resource errors
    PORT_EXHAUSTED: 'PORT_EXHAUSTED',
    PORT_IN_USE: 'PORT_IN_USE',
    WORKTREE_NOT_FOUND: 'WORKTREE_NOT_FOUND',
    WORKTREE_ALREADY_EXISTS: 'WORKTREE_ALREADY_EXISTS',
    PID_FILE_EXISTS: 'PID_FILE_EXISTS',
    PROCESS_NOT_RUNNING: 'PROCESS_NOT_RUNNING',
    // Security errors
    PATH_TRAVERSAL: 'PATH_TRAVERSAL',
    UNAUTHORIZED: 'UNAUTHORIZED',
    FORBIDDEN: 'FORBIDDEN',
    // System errors
    DATABASE_ERROR: 'DATABASE_ERROR',
    FILESYSTEM_ERROR: 'FILESYSTEM_ERROR',
    GIT_ERROR: 'GIT_ERROR',
    TIMEOUT: 'TIMEOUT',
    // Generic errors
    UNKNOWN_ERROR: 'UNKNOWN_ERROR',
};
/**
 * Application-specific error class
 *
 * @example
 * ```typescript
 * throw new AppError('INVALID_ISSUE_NO', 'Issue number must be a positive integer', { received: -1 });
 * ```
 */
class AppError extends Error {
    /**
     * Error code - safe to expose to clients
     */
    code;
    /**
     * Additional details - may contain sensitive info, log only
     */
    details;
    /**
     * Timestamp when error occurred
     */
    timestamp;
    constructor(code, message, details) {
        super(message);
        this.name = 'AppError';
        this.code = code;
        this.details = details;
        this.timestamp = new Date().toISOString();
        // Maintains proper stack trace for where our error was thrown (only available on V8)
        if (Error.captureStackTrace) {
            Error.captureStackTrace(this, AppError);
        }
    }
    /**
     * Create a client-safe representation (excludes sensitive details)
     */
    toClientError() {
        return {
            code: this.code,
            message: this.message,
        };
    }
    /**
     * Create a log-safe representation (includes details for debugging)
     */
    toLogError() {
        return {
            code: this.code,
            message: this.message,
            details: this.details,
            timestamp: this.timestamp,
        };
    }
}
exports.AppError = AppError;
/**
 * Factory function to create AppError
 *
 * @param code - Error code from ErrorCode enum
 * @param message - Human-readable error message
 * @param details - Optional additional details (logged, not sent to client)
 * @returns AppError instance
 *
 * @example
 * ```typescript
 * throw createAppError(ErrorCode.PORT_EXHAUSTED, 'No available ports in range', { range: [3001, 3100] });
 * ```
 */
function createAppError(code, message, details) {
    return new AppError(code, message, details);
}
/**
 * Type guard to check if an error is an AppError
 *
 * @param error - Error to check
 * @returns true if error is an AppError
 */
function isAppError(error) {
    return error instanceof AppError;
}
/**
 * Wrap unknown error into AppError
 *
 * @param error - Unknown error
 * @param defaultCode - Default error code if error is not AppError
 * @returns AppError instance
 */
function wrapError(error, defaultCode = exports.ErrorCode.UNKNOWN_ERROR) {
    if (isAppError(error)) {
        return error;
    }
    if (error instanceof Error) {
        return new AppError(defaultCode, error.message, { originalError: error.name });
    }
    return new AppError(defaultCode, String(error));
}
/**
 * Get error message from unknown error
 *
 * @param error - Unknown error
 * @returns Error message string
 */
function getErrorMessage(error) {
    if (error instanceof Error) {
        return error.message;
    }
    return String(error);
}
