import { z } from "zod";
import { SCENARIO_CATEGORIES } from "./TestRecommendation.js";
import { TestType } from "./TestTypes.js";
/**
 * Repository Analysis Types
 * Comprehensive structure for analyzing code repositories
 */
export var AnalysisScope;
(function (AnalysisScope) {
    AnalysisScope["FullRepo"] = "full_repo";
    AnalysisScope["CurrentBranchDiff"] = "current_branch_diff";
})(AnalysisScope || (AnalysisScope = {}));
/** Returns true when the analysis was scoped to the current branch diff (PR mode). */
export function isDiff(scope) {
    return scope === AnalysisScope.CurrentBranchDiff;
}
export var ScenarioSource;
(function (ScenarioSource) {
    ScenarioSource["CodeInferred"] = "code-inferred";
    ScenarioSource["Trace"] = "trace";
    ScenarioSource["Documentation"] = "documentation";
    ScenarioSource["AgentEnriched"] = "agent-enriched";
})(ScenarioSource || (ScenarioSource = {}));
// ── Zod schemas ──
export const analysisScopeSchema = z.nativeEnum(AnalysisScope);
export const paramInfoSchema = z.object({
    name: z.string(),
    type: z.string(),
    required: z.boolean(),
    description: z.string().optional(),
    constraints: z.string().optional(),
});
export const cookieInfoSchema = z.object({
    name: z.string(),
    sampleValue: z.string(),
    purpose: z.string(),
    httpOnly: z.boolean(),
    secure: z.boolean(),
});
export const endpointInteractionSchema = z.object({
    description: z.string(),
    type: z.enum(["success", "error", "edge-case"]),
    request: z.object({
        contentType: z.string().optional(),
        body: z.record(z.any()).optional(),
        headers: z.record(z.string()).optional(),
        queryParams: z.record(z.any()).optional(),
    }),
    response: z.object({
        statusCode: z.number(),
        description: z.string(),
        body: z.record(z.any()).optional(),
        headers: z.record(z.string()).optional(),
        cookies: z.array(cookieInfoSchema).optional(),
    }),
});
export const endpointMethodSchema = z.object({
    method: z.string(),
    description: z.string(),
    queryParams: z.array(paramInfoSchema),
    authRequired: z.boolean(),
    authType: z.string().optional(),
    scopes: z.array(z.string()).optional(),
    sourceFile: z.string(),
    interactions: z.array(endpointInteractionSchema),
    dependsOn: z.array(z.string()).optional(),
    createsResource: z.string().optional(),
});
export const enrichedEndpointSchema = z.object({
    path: z.string(),
    resourceGroup: z.string(),
    pathParams: z.array(paramInfoSchema),
    methods: z.array(endpointMethodSchema),
});
export const chainingRefSchema = z.object({
    sourceStep: z.number(),
    sourceField: z.string(),
    sourceLocation: z.enum(["body", "header", "cookie"]),
    targetParam: z.string(),
    targetLocation: z.enum(["path", "body", "query", "header", "cookie"]),
});
export const scenarioStepSchema = z.object({
    order: z.number(),
    method: z.string(),
    path: z.string(),
    description: z.string(),
    interactionType: z.enum(["success", "error", "edge-case"]),
    requestBody: z.record(z.any()).optional(),
    queryParams: z.record(z.any()).optional(),
    responseBody: z.record(z.any()).optional(),
    expectedStatusCode: z.number(),
    expectedResponseFields: z.array(z.string()).optional(),
    chainsFrom: z
        .union([chainingRefSchema, z.array(chainingRefSchema)])
        .optional(),
    bodyMustInclude: z.array(z.string()).optional(),
});
export const draftedScenarioSchema = z.object({
    scenarioName: z.string(),
    description: z.string(),
    category: z.enum(SCENARIO_CATEGORIES),
    priority: z.enum(["high", "medium", "low"]),
    steps: z.array(scenarioStepSchema),
    chainingKeys: z.array(z.string()),
    requiresAuth: z.boolean(),
    estimatedComplexity: z.enum(["simple", "moderate", "complex"]),
    source: z.nativeEnum(ScenarioSource).optional(),
    testType: z.nativeEnum(TestType).optional(),
    bugCatchingTarget: z.string().optional(),
});
export const branchDiffContextSchema = z.object({
    currentBranch: z.string(),
    baseBranch: z.string(),
    changedFiles: z.array(z.string()),
    newEndpoints: z.array(z.object({
        path: z.string(),
        methods: z.array(z.object({
            method: z.string(),
            sourceFile: z.string(),
            interactionCount: z.number(),
        })),
    })),
    modifiedEndpoints: z.array(z.object({
        path: z.string(),
        methods: z.array(z.object({
            method: z.string(),
            sourceFile: z.string(),
            changeType: z.enum(["added", "modified", "removed"]),
        })),
    })),
    removedEndpoints: z.array(z.object({
        path: z.string(),
        methods: z.array(z.object({
            method: z.string(),
            sourceFile: z.string(),
            changeType: z.literal("removed"),
        })),
    })).optional(),
    affectedServices: z.array(z.string()),
    summary: z.string().optional(),
});
export const analysisMetadataSchema = z.object({
    repositoryName: z.string(),
    analysisDate: z.string(),
    scanDepth: z.enum(["quick", "full"]),
    analysisScope: analysisScopeSchema.optional(),
});
export const projectClassificationSchema = z.object({
    projectType: z.enum([
        "rest-api",
        "frontend",
        "full-stack",
        "microservices",
        "library",
        "cli",
        "other",
    ]),
    primaryLanguage: z.string(),
    primaryFramework: z.string(),
    deploymentPattern: z.enum([
        "microservices",
        "full-stack",
        "containerized-monolith",
        "traditional",
        "unknown",
    ]),
});
export const repositoryAnalysisSchema = z.object({
    metadata: analysisMetadataSchema,
    projectClassification: projectClassificationSchema,
    technologyStack: z.object({
        languages: z.array(z.string()),
        frameworks: z.array(z.string()),
        runtime: z.string(),
        keyDependencies: z.array(z.object({
            name: z.string(),
            version: z.string(),
            purpose: z.string(),
        })),
    }),
    businessContext: z.object({
        mainPurpose: z.string(),
        userFlows: z.array(z.string()),
        dataFlows: z.array(z.string()),
        integrationPatterns: z.array(z.string()),
        draftedScenarios: z.array(draftedScenarioSchema),
    }),
    artifacts: z.object({
        openApiSpecs: z.array(z.object({
            path: z.string(),
            version: z.string(),
            endpointCount: z.number(),
            baseUrl: z.string(),
            authType: z.string(),
        })),
        playwrightRecordings: z.array(z.object({
            path: z.string(),
            description: z.string(),
        })),
        traceFiles: z.array(z.object({
            path: z.string(),
            format: z.string(),
            analyzed: z.boolean().optional(),
            userFlows: z.array(z.string()).optional(),
        })),
        notFound: z.array(z.string()),
    }),
    apiEndpoints: z.object({
        totalCount: z.number(),
        baseUrl: z.string(),
        endpoints: z.array(enrichedEndpointSchema),
    }),
    authentication: z.object({
        method: z.string(),
        configLocation: z.string(),
        envVarsRequired: z.array(z.string()),
        setupExample: z.string(),
    }),
    infrastructure: z.object({
        isContainerized: z.boolean(),
        hasDockerCompose: z.boolean(),
        hasKubernetes: z.boolean(),
        hasCiCd: z.boolean(),
        ciCdPlatform: z.string().optional(),
    }),
    existingTests: z.object({
        frameworks: z.array(z.string()),
        coverage: z.object({
            unit: z.number(),
            integration: z.number(),
            e2e: z.number(),
            ui: z.number(),
            load: z.number(),
            contract: z.number(),
            smoke: z.number(),
        }),
        testLocations: z.record(z.string()),
        hasCoverageReports: z.boolean(),
        estimatedCoverage: z.number().optional(),
        relevantExternalTestPaths: z.array(z.string()).optional(),
    }),
    branchDiffContext: branchDiffContextSchema.optional(),
});
