/**
 * @fileoverview Discriminated union types for complex state management
 *
 * This module defines type-safe discriminated union types for various complex state
 * management scenarios in the codebase. Discriminated unions help ensure that code
 * handling different states properly accounts for all possible variants.
 */
import { ErrorCategory } from '../utils/errors/categories.js';
import { AnalysisRunStatus } from '../models/runs.js';
import { MetricDirection, MetricShortcode, MetricThresholdStatus } from './metrics.js';
import { BranchName, CommitOid, RunId } from './branded.js';
import { ReportType, ReportStatus } from '../deepsource.js';
/**
 * -----------------------------------------------------------------------------
 * Error Handling Discriminated Unions
 * -----------------------------------------------------------------------------
 */
/**
 * Base interface for all error types
 */
interface ErrorBase {
    /** Message describing the error */
    message: string;
    /** Error category discriminant */
    category: ErrorCategory;
    /** Additional metadata for the error */
    metadata?: Record<string, unknown>;
}
/**
 * Authentication error (invalid API key, expired token, etc.)
 */
export interface AuthError extends ErrorBase {
    category: ErrorCategory.AUTH;
    /** Token information if available */
    token?: {
        /** Whether the token was present */
        present: boolean;
        /** Whether the token was expired */
        expired?: boolean;
    };
}
/**
 * Network error (connection issues, DNS failures, etc.)
 */
export interface NetworkError extends ErrorBase {
    category: ErrorCategory.NETWORK;
    /** The URL that failed */
    url?: string;
    /** Information about the connection */
    connection?: {
        /** Whether a connection was established */
        established: boolean;
        /** Time spent trying to connect */
        timeSpent?: number;
    };
}
/**
 * Server error (500 errors, backend failures, etc.)
 */
export interface ServerError extends ErrorBase {
    category: ErrorCategory.SERVER;
    /** HTTP status code if available */
    statusCode?: number;
    /** Server response if available */
    response?: unknown;
}
/**
 * Client error (400 errors, invalid input, etc.)
 */
export interface ClientError extends ErrorBase {
    category: ErrorCategory.CLIENT;
    /** HTTP status code if available */
    statusCode?: number;
    /** Validation errors if available */
    validationErrors?: Record<string, string>;
}
/**
 * Timeout error (request took too long)
 */
export interface TimeoutError extends ErrorBase {
    category: ErrorCategory.TIMEOUT;
    /** The timeout limit in milliseconds */
    timeoutLimit?: number;
    /** Time spent before timeout */
    timeSpent?: number;
}
/**
 * Rate limit error (too many requests)
 */
export interface RateLimitError extends ErrorBase {
    category: ErrorCategory.RATE_LIMIT;
    /** When the rate limit resets */
    resetAt?: string;
    /** Request limit information */
    limit?: {
        /** Max requests allowed */
        max: number;
        /** Remaining requests */
        remaining: number;
    };
}
/**
 * Schema error (GraphQL schema issues)
 */
export interface SchemaError extends ErrorBase {
    category: ErrorCategory.SCHEMA;
    /** The problematic field or type */
    field?: string;
    /** Original GraphQL error */
    graphqlErrors?: Array<{
        message: string;
        path?: string[];
    }>;
}
/**
 * Not found error (resource doesn't exist)
 */
export interface NotFoundError extends ErrorBase {
    category: ErrorCategory.NOT_FOUND;
    /** Resource that wasn't found */
    resource?: string;
    /** ID or key that was looked up */
    identifier?: string;
}
/**
 * Format error (data in unexpected format)
 */
export interface FormatError extends ErrorBase {
    category: ErrorCategory.FORMAT;
    /** Expected format */
    expected?: string;
    /** Received format */
    received?: string;
}
/**
 * Other/unknown errors
 */
export interface OtherError extends ErrorBase {
    category: ErrorCategory.OTHER;
}
/**
 * Union type for all possible error types
 */
export type ApiError = AuthError | NetworkError | ServerError | ClientError | TimeoutError | RateLimitError | SchemaError | NotFoundError | FormatError | OtherError;
/**
 * Type guard to check if an API error belongs to a specific error category
 *
 * This function performs a runtime check on the error's category discriminant
 * to determine if it matches the requested category. Use this with type narrowing
 * to access category-specific properties safely.
 *
 * @example
 * ```typescript
 * if (isErrorOfCategory(error, ErrorCategory.NOT_FOUND)) {
 *   // TypeScript knows this is a NotFoundError now
 *   console.log(error.resource); // Safely access NotFoundError property
 * }
 * ```
 *
 * @param error - The API error object to check
 * @param category - The error category to test against
 * @returns True if the error is of the specified category, false otherwise
 * @public
 */
export declare function isErrorOfCategory(error: ApiError, category: ErrorCategory): boolean;
/**
 * -----------------------------------------------------------------------------
 * API Response Discriminated Unions
 * -----------------------------------------------------------------------------
 */
/**
 * Base interface for API responses
 */
interface ApiResponseBase {
    /** Whether the request was successful */
    success: boolean;
}
/**
 * Successful API response
 */
export interface SuccessResponse<T> extends ApiResponseBase {
    success: true;
    /** Response data */
    data: T;
}
/**
 * Failed API response
 */
export interface ErrorResponse extends ApiResponseBase {
    success: false;
    /** Error information */
    error: ApiError;
}
/**
 * Union type for API responses
 */
export type ApiResponse<T> = SuccessResponse<T> | ErrorResponse;
/**
 * Type guard to check if an API response was successful
 *
 * This function enables safe handling of API responses by distinguishing between
 * success and error cases in a type-safe manner. It acts as a TypeScript type predicate,
 * allowing the compiler to narrow the type when used in conditions.
 *
 * @example
 * ```typescript
 * const response = await fetchData();
 *
 * if (isSuccessResponse(response)) {
 *   // TypeScript knows this is a SuccessResponse<T> now
 *   console.log(response.data); // Safely access response.data
 * } else {
 *   // TypeScript knows this is an ErrorResponse now
 *   console.error(response.error.message); // Safely access error properties
 * }
 * ```
 *
 * @param response - The API response to check
 * @returns Type predicate indicating whether the response is a successful response
 * @typeParam T - The type of data contained in a successful response
 * @public
 */
export declare function isSuccessResponse<T>(response: ApiResponse<T>): response is SuccessResponse<T>;
/**
 * -----------------------------------------------------------------------------
 * Run Status Discriminated Unions
 * -----------------------------------------------------------------------------
 */
/**
 * Base interface for run states
 */
interface RunStateBase {
    /** Run status discriminant */
    status: AnalysisRunStatus;
    /** Run ID */
    runId: RunId;
    /** Commit hash */
    commitOid: CommitOid;
    /** Branch name */
    branchName: BranchName;
    /** Base commit hash */
    baseOid: CommitOid;
    /** Timestamp when the run was created */
    createdAt: string;
    /** Timestamp when the run was last updated */
    updatedAt: string;
}
/**
 * Run in pending state
 */
export interface PendingRun extends RunStateBase {
    status: 'PENDING';
    /** Position in queue if available */
    queuePosition?: number;
    /** Estimated start time if available */
    estimatedStartTime?: string;
}
/**
 * Run in progress state
 */
export interface RunningRun extends RunStateBase {
    status: 'READY';
    /** Current progress percentage if available */
    progress?: number;
    /** Current stage of analysis if available */
    currentStage?: string;
    /** Estimated completion time if available */
    estimatedCompletionTime?: string;
}
/**
 * Successful run
 */
export interface SuccessfulRun extends RunStateBase {
    status: 'SUCCESS';
    /** When the run finished */
    finishedAt: string;
    /** Summary of results */
    summary: {
        /** Number of new issues introduced */
        occurrencesIntroduced: number;
        /** Number of issues resolved */
        occurrencesResolved: number;
        /** Number of issues suppressed */
        occurrencesSuppressed: number;
        /** Analyzer distribution */
        analyzerDistribution?: Array<{
            analyzer: string;
            count: number;
        }>;
        /** Category distribution */
        categoryDistribution?: Array<{
            category: string;
            count: number;
        }>;
    };
}
/**
 * Failed run (error occurred)
 */
export interface FailedRun extends RunStateBase {
    status: 'FAILURE';
    /** When the run failed */
    finishedAt: string;
    /** Error information if available */
    error?: {
        /** Error message */
        message: string;
        /** Error code if available */
        code?: string;
    };
}
/**
 * Timed out run
 */
export interface TimedOutRun extends RunStateBase {
    status: 'TIMEOUT';
    /** When the run timed out */
    finishedAt: string;
    /** Timeout information */
    timeout?: {
        /** Time limit in seconds */
        limitSeconds: number;
        /** Partial results if available */
        partialResultsAvailable: boolean;
    };
}
/**
 * Cancelled run
 */
export interface CancelledRun extends RunStateBase {
    status: 'CANCEL';
    /** When the run was cancelled */
    finishedAt: string;
    /** Who cancelled the run if available */
    cancelledBy?: string;
    /** Reason for cancellation if available */
    cancellationReason?: string;
}
/**
 * Skipped run
 */
export interface SkippedRun extends RunStateBase {
    status: 'SKIPPED';
    /** When the run was skipped */
    finishedAt: string;
    /** Reason for skipping */
    skipReason?: string;
}
/**
 * Union type for run states
 */
export type RunState = PendingRun | RunningRun | SuccessfulRun | FailedRun | TimedOutRun | CancelledRun | SkippedRun;
/**
 * Type guard to check if a run is in a specific state
 * @param run Run to check
 * @param status Status to check for
 * @returns Whether the run is in the specified state
 */
/**
 * Type guard to check if a run is in a specific state
 *
 * This generic type guard determines if a run is in a particular state based on
 * its status discriminant. It enables type-safe access to state-specific properties
 * after TypeScript narrows the type.
 *
 * @example
 * ```typescript
 * // Check if run is successful and access success-specific properties
 * if (isRunInState<SuccessfulRun>(run, 'SUCCESS')) {
 *   // TypeScript knows this is a SuccessfulRun now
 *   console.log(run.finishedAt);
 *   console.log(run.summary.occurrencesIntroduced);
 * }
 *
 * // Check if run is in progress and access progress-specific properties
 * if (isRunInState<RunningRun>(run, 'READY')) {
 *   // TypeScript knows this is a RunningRun now
 *   console.log(run.progress);
 *   console.log(run.currentStage);
 * }
 * ```
 *
 * @param run - The run object to check
 * @param status - The status to test against
 * @returns Type predicate indicating whether the run is in the specified state
 * @typeParam T - The specific run state type to check for (must extend RunState)
 * @public
 */
export declare function isRunInState<T extends RunState>(run: RunState, status: AnalysisRunStatus): run is T;
/**
 * -----------------------------------------------------------------------------
 * Report Type Discriminated Unions
 * -----------------------------------------------------------------------------
 */
/**
 * Base interface for compliance reports
 */
interface ComplianceReportBase {
    /** Report type discriminant */
    type: ReportType;
    /** Report title */
    title: string;
    /** Current compliance value (percentage or score) */
    currentValue: number;
    /** Compliance status */
    status: ReportStatus;
    /** Trend data if available */
    trends?: Record<string, unknown>;
}
/**
 * OWASP Top 10 report
 */
export interface OwaspTop10Report extends ComplianceReportBase {
    type: ReportType.OWASP_TOP_10;
    /** OWASP Top 10 categories with issues */
    categories: Array<{
        /** OWASP category key */
        key: string;
        /** Category title */
        title: string;
        /** Issue counts by severity */
        issues: {
            critical: number;
            major: number;
            minor: number;
            total: number;
        };
    }>;
}
/**
 * SANS Top 25 report
 */
export interface SansTop25Report extends ComplianceReportBase {
    type: ReportType.SANS_TOP_25;
    /** SANS Top 25 categories with issues */
    categories: Array<{
        /** SANS category key */
        key: string;
        /** Category title */
        title: string;
        /** Issue counts by severity */
        issues: {
            critical: number;
            major: number;
            minor: number;
            total: number;
        };
    }>;
}
/**
 * MISRA-C report
 */
export interface MisraCReport extends ComplianceReportBase {
    type: ReportType.MISRA_C;
    /** MISRA violation categories */
    categories: Array<{
        /** MISRA rule key */
        key: string;
        /** Rule title */
        title: string;
        /** Issue counts by severity */
        issues: {
            critical: number;
            major: number;
            minor: number;
            total: number;
        };
    }>;
}
/**
 * Code coverage report
 */
export interface CodeCoverageReport extends ComplianceReportBase {
    type: ReportType.CODE_COVERAGE;
    /** Coverage by type */
    coverage: {
        /** Line coverage percentage */
        line?: number;
        /** Branch coverage percentage */
        branch?: number;
        /** Statement coverage percentage */
        statement?: number;
        /** Function coverage percentage */
        function?: number;
    };
    /** Coverage trend over time */
    trend?: Array<{
        /** Date of the data point */
        date: string;
        /** Coverage value */
        value: number;
    }>;
}
/**
 * Issues prevented report
 */
export interface IssuesPreventedReport extends ComplianceReportBase {
    type: ReportType.ISSUES_PREVENTED;
    /** Issues prevented by severity */
    prevented: {
        /** Critical issues prevented */
        critical: number;
        /** Major issues prevented */
        major: number;
        /** Minor issues prevented */
        minor: number;
        /** Total issues prevented */
        total: number;
    };
    /** Percentage of issues that were prevented */
    preventionRate: number;
}
/**
 * Union type for all report types
 */
export type ComplianceReport = OwaspTop10Report | SansTop25Report | MisraCReport | CodeCoverageReport | IssuesPreventedReport;
/**
 * Type guard to check if a compliance report is of a specific type
 *
 * This generic type guard determines if a compliance report is of a particular type
 * based on its type discriminant. It enables type-safe access to report-type-specific
 * properties after TypeScript narrows the type.
 *
 * @example
 * ```typescript
 * // Check if report is an OWASP Top 10 report
 * if (isReportOfType<OwaspTop10Report>(report, ReportType.OWASP_TOP_10)) {
 *   // TypeScript knows this is an OwaspTop10Report now
 *   console.log(report.owaspCategories);
 *   console.log(report.vulnerabilityCount);
 * }
 * ```
 *
 * @param report - The compliance report to check
 * @param type - The report type to test against
 * @returns Type predicate indicating whether the report is of the specified type
 * @typeParam T - The specific report type to check for (must extend ComplianceReport)
 * @public
 */
export declare function isReportOfType<T extends ComplianceReport>(report: ComplianceReport, type: ReportType): report is T;
/**
 * -----------------------------------------------------------------------------
 * Metric Status Discriminated Unions
 * -----------------------------------------------------------------------------
 */
/**
 * Base interface for metric states
 */
interface MetricStateBase {
    /** Metric shortcode */
    shortcode: MetricShortcode;
    /** Metric name */
    name: string;
    /** Unit of measurement */
    unit: string;
    /** Direction in which higher values are considered positive */
    positiveDirection: MetricDirection;
    /** Current metric value */
    value: number;
    /** Status discriminant */
    status: MetricThresholdStatus;
}
/**
 * Passing metric
 */
export interface PassingMetric extends MetricStateBase {
    status: MetricThresholdStatus.PASSING;
    /** The threshold that was met or exceeded */
    threshold: number;
    /** By how much the metric exceeds the threshold */
    margin?: number;
}
/**
 * Failing metric
 */
export interface FailingMetric extends MetricStateBase {
    status: MetricThresholdStatus.FAILING;
    /** The threshold that wasn't met */
    threshold: number;
    /** By how much the metric falls short of the threshold */
    gap?: number;
    /** Recommendations for improving the metric */
    recommendations?: string[];
}
/**
 * Metric with unknown status (no threshold set)
 */
export interface UnknownMetric extends MetricStateBase {
    status: MetricThresholdStatus.UNKNOWN;
    /** Whether a threshold is recommended */
    thresholdRecommended?: boolean;
    /** Recommended threshold value if available */
    recommendedThreshold?: number;
}
/**
 * Union type for metric states
 */
export type MetricState = PassingMetric | FailingMetric | UnknownMetric;
/**
 * Type guard to check if a metric is in a specific threshold state
 *
 * This generic type guard determines if a quality metric is in a particular threshold
 * state based on its status discriminant. It enables type-safe access to state-specific
 * properties after TypeScript narrows the type.
 *
 * @example
 * ```typescript
 * // Check if metric is passing its threshold
 * if (isMetricInState<PassingMetric>(metric, MetricThresholdStatus.PASS)) {
 *   // TypeScript knows this is a PassingMetric now
 *   console.log(metric.passPercentage);
 *   console.log(metric.margin);
 * }
 *
 * // Check if metric is failing its threshold
 * if (isMetricInState<FailingMetric>(metric, MetricThresholdStatus.FAIL)) {
 *   // TypeScript knows this is a FailingMetric now
 *   console.log(metric.thresholdDelta);
 *   console.log(metric.recommendedThreshold);
 * }
 * ```
 *
 * @param metric - The metric to check
 * @param status - The threshold status to test against
 * @returns Type predicate indicating whether the metric is in the specified state
 * @typeParam T - The specific metric state to check for (must extend MetricState)
 * @public
 */
export declare function isMetricInState<T extends MetricState>(metric: MetricState, status: MetricThresholdStatus): metric is T;
export {};
