"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.BlueprintLoader = void 0;
const fs = __importStar(require("fs-extra"));
const path = __importStar(require("path"));
const BlueprintSchema_1 = require("../types/BlueprintSchema");
const BUILT_IN_BLUEPRINTS = {
    "nextjs-pwa": {
        blueprintId: "nextjs-pwa",
        name: "Next.js PWA Starter",
        version: "1.0.0",
        severityWeight: { high: 20, medium: 10, low: 3 },
        stack: {
            framework: "nextjs",
            css: "tailwind",
            tools: ["pwa", "service-worker"]
        },
        directories: {
            required: ["app", "public", "public/icons"]
        },
        files: {
            required: [
                {
                    path: "public/manifest.webmanifest",
                    description: "PWA Web App Manifest file detailing icons, name, and background colors.",
                    expectedContent: JSON.stringify({
                        name: "My PWA App",
                        short_name: "PWA",
                        start_url: "/",
                        display: "standalone",
                        background_color: "#0f172a",
                        theme_color: "#00d9ff",
                        icons: [
                            {
                                src: "/icons/icon-192.png",
                                sizes: "192x192",
                                type: "image/png"
                            }
                        ]
                    }, null, 2),
                    autoFixable: true,
                    fixOperation: "create-file",
                    requiresHumanReview: false,
                    severity: "high"
                },
                {
                    path: "app/globals.css",
                    description: "Tailwind CSS global definitions file",
                    expectedContent: "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
                    autoFixable: true,
                    fixOperation: "create-file",
                    requiresHumanReview: false,
                    severity: "medium"
                }
            ]
        },
        conventions: [
            {
                id: "app-layout",
                name: "Root Layout Convention",
                description: "Root layout layout.tsx must exist inside the app/ directory.",
                pathPattern: "app/layout.tsx",
                severity: "high"
            }
        ],
        qualityGates: [
            {
                id: "tsconfig",
                name: "tsconfig.json Check",
                command: "test -f tsconfig.json",
                severity: "medium"
            }
        ]
    },
    "auth-admin": {
        blueprintId: "auth-admin",
        name: "Authentication & Role Management Admin",
        version: "1.0.0",
        extends: ["nextjs-pwa"], // Inherits PWA setup!
        severityWeight: { high: 25, medium: 15, low: 5 },
        stack: {
            framework: "nextjs",
            css: "tailwind",
            tools: ["auth", "role-management"]
        },
        directories: {
            required: ["app/admin", "app/admin/users", "components/admin", "middleware"]
        },
        files: {
            required: [
                {
                    path: "middleware.ts",
                    description: "Authentication and Route Protection Middleware",
                    expectedContent: `import { NextResponse } from "next/server";\nimport type { NextRequest } from "next/server";\n\nexport function middleware(request: NextRequest) {\n  const token = request.cookies.get("session");\n  const isAuthRoute = request.nextUrl.pathname.startsWith("/login");\n  const isAdminRoute = request.nextUrl.pathname.startsWith("/admin");\n\n  if (!token && isAdminRoute) {\n    return NextResponse.redirect(new URL("/login", request.url));\n  }\n  return NextResponse.next();\n}\n\nexport const config = {\n  matcher: ["/admin/:path*", "/dashboard/:path*"],\n};\n`,
                    autoFixable: true,
                    fixOperation: "create-file",
                    requiresHumanReview: true, // Needs verification because routing details vary
                    severity: "high"
                },
                {
                    path: "app/admin/page.tsx",
                    description: "Admin Panel Dashboard Overview Component",
                    expectedContent: `export default function AdminDashboard() {\n  return (\n    <div className="p-8">\n      <h1 className="text-3xl font-bold mb-4 text-[#00D9FF]">Admin Dashboard</h1>\n      <p className="text-gray-400">System overview, metrics, and role control center.</p>\n    </div>\n  );\n}\n`,
                    autoFixable: true,
                    fixOperation: "create-file",
                    requiresHumanReview: false,
                    severity: "medium"
                },
                {
                    path: "app/admin/users/page.tsx",
                    description: "Admin User List and Invitation Form page",
                    expectedContent: `export default function AdminUsersPage() {\n  return (\n    <div className="p-8">\n      <h1 className="text-2xl font-bold mb-4">User Management</h1>\n      <div className="border border-gray-800 rounded p-4 bg-[#1E293B]">\n        <p className="text-gray-400">Manage user roles, capabilities, and active invites.</p>\n      </div>\n    </div>\n  );\n}\n`,
                    autoFixable: true,
                    fixOperation: "create-file",
                    requiresHumanReview: false,
                    severity: "medium"
                }
            ]
        }
    },
    "daily-guess": {
        blueprintId: "daily-guess",
        name: "Daily Guess Sandbox App",
        version: "1.0.0",
        extends: ["nextjs-pwa"],
        severityWeight: { high: 15, medium: 8, low: 2 },
        stack: {
            framework: "nextjs",
            css: "tailwind",
            tools: ["gameplay", "daily-reset"]
        },
        directories: {
            required: ["app/guess", "components", "lib", "actions"]
        },
        files: {
            required: [
                {
                    path: "app/guess/page.tsx",
                    description: "Daily Game Play page for Guessing platform",
                    expectedContent: `export default function GuessPage() {\n  return (\n    <div className="min-h-screen flex flex-col items-center justify-center p-6 bg-[#0F172A] text-white">\n      <h1 className="text-4xl font-black text-[#00D9FF] mb-2">How Lucky Am I Today?</h1>\n      <p className="text-gray-400 mb-6">Enter a number and test your luck for today!</p>\n    </div>\n  );\n}\n`,
                    autoFixable: true,
                    fixOperation: "create-file",
                    requiresHumanReview: false,
                    severity: "medium"
                },
                {
                    path: "lib/daily.ts",
                    description: "Seed calculation utility for daily targets",
                    expectedContent: `export function getDailyTarget(): number {\n  const today = new Date().toDateString();\n  // Deterministic target between 1 and 100 based on seed date\n  let hash = 0;\n  for (let i = 0; i < today.length; i++) {\n    hash = (hash << 5) - hash + today.charCodeAt(i);\n    hash |= 0;\n  }\n  return Math.abs(hash % 100) + 1;\n}\n`,
                    autoFixable: true,
                    fixOperation: "create-file",
                    requiresHumanReview: false,
                    severity: "medium"
                }
            ]
        }
    }
};
class BlueprintLoader {
    constructor(baseDir) {
        this.baseDir = baseDir || process.cwd();
        this.localBlueprintsDir = path.join(this.baseDir, ".mycontext", "blueprints");
    }
    /**
     * List all blueprints (both built-in and local-workspace blueprints)
     */
    async listBlueprints() {
        const list = [];
        // Add built-ins
        for (const [id, bp] of Object.entries(BUILT_IN_BLUEPRINTS)) {
            list.push({
                id,
                name: bp.name,
                version: bp.version,
                description: `Built-in blueprint for ${bp.stack.framework} utilizing ${bp.stack.tools?.join(", ") || "standard configs"}`
            });
        }
        // Add local workspace blueprints
        if (await fs.pathExists(this.localBlueprintsDir)) {
            try {
                const files = await fs.readdir(this.localBlueprintsDir);
                for (const file of files) {
                    if (file.endsWith(".json")) {
                        const filePath = path.join(this.localBlueprintsDir, file);
                        try {
                            const content = await fs.readJson(filePath);
                            const parsed = BlueprintSchema_1.BlueprintSchema.safeParse(content);
                            if (parsed.success) {
                                // If it is already in the list, local overrides it
                                const idx = list.findIndex(item => item.id === parsed.data.blueprintId);
                                const info = {
                                    id: parsed.data.blueprintId,
                                    name: parsed.data.name,
                                    version: parsed.data.version,
                                    description: `Local blueprint from .mycontext/blueprints/${file}`
                                };
                                if (idx !== -1) {
                                    list[idx] = info;
                                }
                                else {
                                    list.push(info);
                                }
                            }
                        }
                        catch (e) {
                            // Ignore invalid JSON files during listing
                        }
                    }
                }
            }
            catch (e) {
                // Directory read error
            }
        }
        return list;
    }
    /**
     * Load and validate a blueprint by ID or path
     */
    async loadBlueprint(blueprintIdOrPath) {
        let rawBlueprint = null;
        // 1. Try built-ins
        if (BUILT_IN_BLUEPRINTS[blueprintIdOrPath]) {
            rawBlueprint = BUILT_IN_BLUEPRINTS[blueprintIdOrPath];
        }
        else {
            // 2. Try file path
            const directPath = path.isAbsolute(blueprintIdOrPath)
                ? blueprintIdOrPath
                : path.resolve(blueprintIdOrPath);
            if (await fs.pathExists(directPath) && (await fs.stat(directPath)).isFile()) {
                rawBlueprint = await fs.readJson(directPath);
            }
            else {
                // 3. Try local blueprints directory by id
                const localPath = path.join(this.localBlueprintsDir, `${blueprintIdOrPath}.json`);
                if (await fs.pathExists(localPath)) {
                    rawBlueprint = await fs.readJson(localPath);
                }
            }
        }
        if (!rawBlueprint) {
            throw new Error(`Blueprint not found: ${blueprintIdOrPath}`);
        }
        // Validate using Zod
        const result = BlueprintSchema_1.BlueprintSchema.safeParse(rawBlueprint);
        if (!result.success) {
            throw new Error(`Invalid blueprint schema: ${result.error.message}`);
        }
        // Resolve extends
        return this.resolveInheritance(result.data);
    }
    /**
     * Recursively merge extends parameters
     */
    async resolveInheritance(blueprint, visited = new Set()) {
        if (!blueprint.extends || blueprint.extends.length === 0) {
            return blueprint;
        }
        if (visited.has(blueprint.blueprintId)) {
            throw new Error(`Circular inheritance detected in blueprint: ${blueprint.blueprintId}`);
        }
        visited.add(blueprint.blueprintId);
        const mergedDirs = {
            required: [...(blueprint.directories?.required || [])],
            optional: [...(blueprint.directories?.optional || [])]
        };
        const mergedFiles = {
            required: [...(blueprint.files?.required || [])],
            optional: [...(blueprint.files?.optional || [])]
        };
        const mergedConventions = [...(blueprint.conventions || [])];
        const mergedQualityGates = [...(blueprint.qualityGates || [])];
        const mergedConformanceChecks = [...(blueprint.conformanceChecks || [])];
        const mergedSafeFixes = [...(blueprint.safeAutoFixes || [])];
        for (const parentId of blueprint.extends) {
            const parent = await this.loadBlueprint(parentId);
            const fullyResolvedParent = await this.resolveInheritance(parent, new Set(visited));
            if (fullyResolvedParent.directories?.required) {
                mergedDirs.required = Array.from(new Set([...mergedDirs.required, ...fullyResolvedParent.directories.required]));
            }
            if (fullyResolvedParent.directories?.optional) {
                mergedDirs.optional = Array.from(new Set([...mergedDirs.optional, ...fullyResolvedParent.directories.optional]));
            }
            if (fullyResolvedParent.files?.required) {
                for (const fileReq of fullyResolvedParent.files.required) {
                    if (!mergedFiles.required.some(f => f.path === fileReq.path)) {
                        mergedFiles.required.push(fileReq);
                    }
                }
            }
            if (fullyResolvedParent.files?.optional) {
                for (const fileReq of fullyResolvedParent.files.optional) {
                    if (!mergedFiles.optional.some(f => f.path === fileReq.path)) {
                        mergedFiles.optional.push(fileReq);
                    }
                }
            }
            if (fullyResolvedParent.conventions) {
                for (const rule of fullyResolvedParent.conventions) {
                    if (!mergedConventions.some(c => c.id === rule.id)) {
                        mergedConventions.push(rule);
                    }
                }
            }
            if (fullyResolvedParent.qualityGates) {
                for (const gate of fullyResolvedParent.qualityGates) {
                    if (!mergedQualityGates.some(q => q.id === gate.id)) {
                        mergedQualityGates.push(gate);
                    }
                }
            }
            if (fullyResolvedParent.conformanceChecks) {
                for (const check of fullyResolvedParent.conformanceChecks) {
                    if (!mergedConformanceChecks.some(c => c.id === check.id)) {
                        mergedConformanceChecks.push(check);
                    }
                }
            }
            if (fullyResolvedParent.safeAutoFixes) {
                for (const fix of fullyResolvedParent.safeAutoFixes) {
                    if (!mergedSafeFixes.some(f => f.id === fix.id)) {
                        mergedSafeFixes.push(fix);
                    }
                }
            }
        }
        return {
            ...blueprint,
            directories: mergedDirs,
            files: mergedFiles,
            conventions: mergedConventions,
            qualityGates: mergedQualityGates,
            conformanceChecks: mergedConformanceChecks,
            safeAutoFixes: mergedSafeFixes
        };
    }
}
exports.BlueprintLoader = BlueprintLoader;
//# sourceMappingURL=BlueprintLoader.js.map