import { z } from "zod";
import { logger } from "../../utils/logger.js";
import { getCodeReusePrompt } from "../../prompts/code-reuse.js";
import { codeRefactoringSchema, languageSchema, } from "../../types/TestTypes.js";
import { SKYRAMP_UTILS_HEADER } from "../../utils/utils.js";
import { AnalyticsService } from "../../services/AnalyticsService.js";
import { stageGeneratedPaths } from "../../utils/gitStaging.js";
const codeReuseSchema = z.object({
    testFile: z
        .string()
        .describe("The test file to analyze for code reuse opportunities"),
    language: languageSchema.shape.language,
    framework: languageSchema.shape.framework,
    modularizeCode: codeRefactoringSchema.shape.modularizeCode,
    prompt: z
        .string()
        .describe("The code content to analyze and optimize for code reuse"),
});
const TOOL_NAME = "skyramp_reuse_code";
export function registerCodeReuseTool(server) {
    server.registerTool(TOOL_NAME, {
        description: `Analyzes code for reuse opportunities and enforces code reuse principles.

      This tool helps identify and reuse ONLY EXISTING helper functions from other test files (grep based on "${SKYRAMP_UTILS_HEADER}").

      **CRITICAL RULES - VIOLATION WILL RESULT IN ERROR:**
      1. THIS TOOL MUST BE CALLED IF DURING THE TEST GENERATION THE CODE REUSE FLAG IS SET TO TRUE EXPLICITLY
      2. DO NOT create new helper functions - only find and reuse existing ones
      3. ONLY create a utils file if ACTUAL helper functions (with signatures) exist in OTHER test files
      4. DO NOT create utils files for repetitive patterns - that's refactoring, not reuse
      5. DO NOT extract patterns from current or other test files - only move existing functions
      6. If other test files are identical/similar with no helper functions, DO NOTHING
      7. Helper functions must have explicit function definitions, not just patterns
      8. If no existing helper functions found, test file remains unchanged


      **WORKFLOW SUMMARY:**
      1. Check existing utils with header ${SKYRAMP_UTILS_HEADER} → reuse if found WITHOUT ANY OTHER CHANGES
      2. Search OTHER test files (not current test file) for local helpers with header ${SKYRAMP_UTILS_HEADER}
      3. **ONLY IF** reusable helpers are found in OTHER test files → move to utils and update imports
      4. **IF NO** existing utils or reusable helpers are found in test files then reuse is complete, without creating any files or changes to the test files
      5. Verify no duplicate code remains and tests work as expected
      6. **MANDATORY**: After code reuse is complete, proceed to modularization by calling skyramp_modularization tool ONLY for UI, E2E, INTEGRATION or LOAD tests generated from traces.

      **WHEN TO SKIP (DO NOTHING):**
      - Other test files only have repetitive patterns, no helper functions
      - Other test files are essentially identical to current file
      - No actual function definitions found in other test files

      **MANDATORY**: ONLY ALLOW CODE REUSE IF THE IS TRACE BASED FLAG IS SET TO TRUE ELSE DO NOT ALLOW CODE REUSE AND LEAVE THE TEST FILE AS IS.
      **CRITICAL**: NON TRACE BASED TESTS ARE ALREADY MODULARIZED AND DO NOT NEED CODE REUSE.
      The tool will provide step-by-step instructions that MUST be followed exactly.

      **POM-AWARE MODE (TypeScript/Playwright only):**
      For projects with \`language: "typescript"\` and \`framework: "playwright"\`, this tool first checks whether the project has an existing Page Object Model (POM) library (\`pageobjects/\` directories or \`*.page.ts\` files). If POMs are found, the test is refactored to use those POM classes and methods — replacing raw inline locators with the existing abstractions. SkyrampUtils consolidation is skipped on this path. If no POMs are found, the tool falls back to the standard SkyrampUtils path. New POM creation is out of scope — existing POMs are reused only. After POM-aware code reuse, do NOT call skyramp_modularization.`,
        inputSchema: codeReuseSchema.shape,
        _meta: {
            keywords: [
                "code reuse",
                "duplicate code",
                "helper functions",
                "import",
                "refactor",
            ],
        },
    }, async (params) => {
        let errorResult;
        try {
            logger.info("Analyzing code for reuse opportunities", {
                testFile: params.testFile,
                language: params.language,
                framework: params.framework,
            });
            // Stage so testbot includes the generated files in its output commit.
            await stageGeneratedPaths(params.testFile);
            const codeReusePrompt = getCodeReusePrompt(params.testFile, params.language, params.framework);
            return {
                content: [
                    {
                        type: "text",
                        text: codeReusePrompt,
                    },
                ],
            };
        }
        catch (error) {
            const errorMessage = `Code reuse analysis failed: ${error.message}`;
            errorResult = {
                content: [
                    {
                        type: "text",
                        text: errorMessage,
                    },
                ],
                isError: true,
            };
            return errorResult;
        }
        finally {
            AnalyticsService.pushMCPToolEvent(TOOL_NAME, errorResult, {
                prompt: params.prompt,
                testFile: params.testFile,
                language: params.language,
                framework: params.framework,
            });
        }
    });
}
