#!/usr/bin/env node
import { i as MuseaVrtRunner, n as generateVrtJsonReport, r as generateVrtReport } from "../vrt-Cv1PK1EF.mjs";
import fs from "node:fs";
import path from "node:path";
//#region src/cli/utils.ts
/**
* CLI utility functions for art file scanning and parsing.
*
* Extracted from cli.ts to keep file sizes manageable.
*/
/** Recursively scan a directory for .art.vue files. */
async function scanArtFiles(root) {
	const files = [];
	async function scan(dir) {
		const entries = await fs.promises.readdir(dir, { withFileTypes: true });
		for (const entry of entries) {
			const fullPath = path.join(dir, entry.name);
			if (entry.name === "node_modules" || entry.name === "dist") continue;
			if (entry.isDirectory()) await scan(fullPath);
			else if (entry.isFile() && entry.name.endsWith(".art.vue")) files.push(fullPath);
		}
	}
	await scan(root);
	return files;
}
/** Parse a single .art.vue file into an ArtFileInfo structure. */
async function parseArtFile(filePath) {
	try {
		const source = await fs.promises.readFile(filePath, "utf-8");
		const titleMatch = source.match(/<art[^>]*\stitle=["']([^"']+)["']/);
		const componentMatch = source.match(/<art[^>]*\scomponent=["']([^"']+)["']/);
		const categoryMatch = source.match(/<art[^>]*\scategory=["']([^"']+)["']/);
		const variants = [];
		const variantRegex = /<variant\s+([^>]*)>([\s\S]*?)<\/variant>/g;
		let match;
		while ((match = variantRegex.exec(source)) !== null) {
			const attrs = match[1];
			const template = match[2].trim();
			const nameMatch = attrs.match(/name=["']([^"']+)["']/);
			const isDefault = /\bdefault\b/.test(attrs);
			const skipVrt = /\bskip-vrt\b/.test(attrs);
			if (nameMatch) variants.push({
				name: nameMatch[1],
				template,
				isDefault,
				skipVrt
			});
		}
		return {
			path: filePath,
			metadata: {
				title: titleMatch?.[1] || path.basename(filePath, ".art.vue"),
				component: componentMatch?.[1],
				category: categoryMatch?.[1],
				tags: [],
				status: "ready"
			},
			variants,
			hasScriptSetup: /<script\s+setup/.test(source),
			hasScript: /<script(?!\s+setup)/.test(source),
			styleCount: (source.match(/<style/g) || []).length
		};
	} catch (error) {
		console.error(`Failed to parse ${filePath}:`, error);
		return null;
	}
}
//#endregion
//#region src/cli/commands.ts
/**
* CLI command handlers for the Musea VRT tool.
*
* Extracted from cli.ts to keep file sizes manageable.
* Contains the runVrt, runApprove, runClean, and runGenerate command implementations.
*/
async function runVrt(options, artFiles) {
	const totalVariants = artFiles.reduce((sum, art) => sum + art.variants.filter((v) => !v.skipVrt).length, 0);
	console.log(`  Testing ${totalVariants} variant(s) across ${artFiles.length} art file(s)\n`);
	const runner = new MuseaVrtRunner({
		snapshotDir: path.join(options.output, "snapshots"),
		threshold: options.threshold,
		ci: options.ci ? {
			failOnDiff: true,
			jsonReport: options.json
		} : void 0
	});
	try {
		console.log("  Launching browser...");
		await runner.init();
		console.log("  Running visual regression tests...\n");
		const results = await runner.runAllTests(artFiles, options.baseUrl);
		const summary = runner.getSummary(results);
		console.log("  Results:");
		console.log("  ---------");
		console.log(`    Passed:  ${summary.passed}`);
		console.log(`    Failed:  ${summary.failed}`);
		console.log(`    New:     ${summary.new}`);
		console.log(`    Skipped: ${summary.skipped}`);
		console.log(`    Total:   ${summary.total}`);
		console.log(`    Duration: ${(summary.duration / 1e3).toFixed(2)}s\n`);
		if (options.a11y) {
			console.log("  Running accessibility audits...\n");
			try {
				const { MuseaA11yRunner } = await import("../a11y/index.mjs");
				const a11yRunner = new MuseaA11yRunner();
				const a11yResults = await a11yRunner.runAudits(artFiles, options.baseUrl, runner);
				const a11ySummary = a11yRunner.getSummary(a11yResults);
				console.log("  A11y Results:");
				console.log("  -------------");
				console.log(`    Components: ${a11ySummary.totalComponents}`);
				console.log(`    Variants:   ${a11ySummary.totalVariants}`);
				console.log(`    Violations: ${a11ySummary.totalViolations}`);
				console.log(`    Critical:   ${a11ySummary.criticalCount}`);
				console.log(`    Serious:    ${a11ySummary.seriousCount}\n`);
				const reportDir = options.output;
				await fs.promises.mkdir(reportDir, { recursive: true });
				if (options.json) {
					const a11yJson = a11yRunner.generateJsonReport(a11yResults);
					const a11yPath = path.join(reportDir, "a11y-report.json");
					await fs.promises.writeFile(a11yPath, a11yJson);
					console.log(`  A11y JSON report: ${a11yPath}\n`);
				} else {
					const a11yHtml = a11yRunner.generateHtmlReport(a11yResults);
					const a11yPath = path.join(reportDir, "a11y-report.html");
					await fs.promises.writeFile(a11yPath, a11yHtml);
					console.log(`  A11y HTML report: ${a11yPath}\n`);
				}
				if (options.ci && (a11ySummary.criticalCount > 0 || a11ySummary.seriousCount > 0)) {
					console.log("  CI mode: Accessibility violations found\n");
					process.exit(1);
				}
			} catch (e) {
				console.warn("  A11y audits skipped:", e instanceof Error ? e.message : String(e));
				console.warn("  Make sure axe-core is installed: npm install axe-core\n");
			}
		}
		if (options.update) {
			console.log("  Updating baselines...");
			const updated = await runner.updateBaselines(results);
			console.log(`  Updated ${updated} baseline(s)\n`);
		}
		const reportDir = options.output;
		await fs.promises.mkdir(reportDir, { recursive: true });
		if (options.json) {
			const jsonReport = generateVrtJsonReport(results, summary);
			const jsonPath = path.join(reportDir, "vrt-report.json");
			await fs.promises.writeFile(jsonPath, jsonReport);
			console.log(`  JSON report: ${jsonPath}\n`);
		} else {
			const htmlReport = generateVrtReport(results, summary);
			const htmlPath = path.join(reportDir, "vrt-report.html");
			await fs.promises.writeFile(htmlPath, htmlReport);
			console.log(`  HTML report: ${htmlPath}\n`);
		}
		if (options.ci && summary.failed > 0) {
			console.log("  CI mode: Exiting with error due to failures\n");
			process.exit(1);
		}
	} finally {
		await runner.close();
	}
}
async function runApprove(options, artFiles) {
	const runner = new MuseaVrtRunner({
		snapshotDir: path.join(options.output, "snapshots"),
		threshold: options.threshold
	});
	try {
		console.log("  Launching browser...");
		await runner.init();
		console.log("  Running tests to find diffs...\n");
		const results = await runner.runAllTests(artFiles, options.baseUrl);
		const failed = results.filter((r) => !r.passed && !r.error);
		if (failed.length === 0) {
			console.log("  No failed tests to approve.\n");
			return;
		}
		const pattern = options.pattern;
		if (pattern) console.log(`  Approving snapshots matching: ${pattern}\n`);
		else console.log(`  Approving all ${failed.length} failed snapshot(s)...\n`);
		const approved = await runner.approveResults(results, pattern);
		console.log(`  Approved ${approved} snapshot(s)\n`);
	} finally {
		await runner.close();
	}
}
async function runClean(options, artFiles) {
	const runner = new MuseaVrtRunner({
		snapshotDir: path.join(options.output, "snapshots"),
		threshold: options.threshold
	});
	console.log("  Scanning for orphaned snapshots...\n");
	const cleaned = await runner.cleanOrphans(artFiles);
	if (cleaned === 0) console.log("  No orphaned snapshots found.\n");
	else console.log(`\n  Cleaned ${cleaned} orphaned snapshot(s)\n`);
}
async function runGenerate(options) {
	if (!options.componentPath) {
		console.error("  Error: Missing component path.");
		console.error("  Usage: musea-vrt generate <component.vue>\n");
		process.exit(1);
	}
	const componentPath = path.resolve(options.componentPath);
	try {
		await fs.promises.access(componentPath);
	} catch {
		console.error(`  Error: File not found: ${componentPath}\n`);
		process.exit(1);
	}
	console.log(`  Generating art file for: ${path.relative(process.cwd(), componentPath)}\n`);
	try {
		const { writeArtFile } = await import("../autogen/index.mjs");
		const outputPath = await writeArtFile(componentPath);
		const relOutput = path.relative(process.cwd(), outputPath);
		console.log(`  Generated: ${relOutput}\n`);
	} catch (e) {
		console.error("  Generation failed:", e instanceof Error ? e.message : String(e));
		process.exit(1);
	}
}
//#endregion
//#region src/cli/index.ts
function parseArgs(args) {
	const options = {
		command: "run",
		update: false,
		config: "vite.config.ts",
		output: ".vize",
		threshold: .1,
		json: false,
		ci: false,
		a11y: false,
		help: false,
		baseUrl: "http://localhost:5173"
	};
	let i = 0;
	if (args.length > 0 && !args[0].startsWith("-")) {
		const sub = args[0];
		if (sub === "approve") {
			options.command = "approve";
			i = 1;
			if (args.length > 1 && !args[1].startsWith("-")) {
				options.pattern = args[1];
				i = 2;
			}
		} else if (sub === "clean") {
			options.command = "clean";
			i = 1;
		} else if (sub === "generate") {
			options.command = "generate";
			i = 1;
			if (args.length > 1 && !args[1].startsWith("-")) {
				options.componentPath = args[1];
				i = 2;
			}
		}
	}
	for (; i < args.length; i++) switch (args[i]) {
		case "-u":
		case "--update":
			options.update = true;
			break;
		case "-c":
		case "--config":
			options.config = args[++i] || "vite.config.ts";
			break;
		case "-o":
		case "--output":
			options.output = args[++i] || ".vize";
			break;
		case "-t":
		case "--threshold":
			options.threshold = parseFloat(args[++i]) || .1;
			break;
		case "--json":
			options.json = true;
			break;
		case "--ci":
			options.ci = true;
			break;
		case "--a11y":
			options.a11y = true;
			break;
		case "-b":
		case "--base-url":
			options.baseUrl = args[++i] || "http://localhost:5173";
			break;
		case "-h":
		case "--help":
			options.help = true;
			break;
	}
	return options;
}
function printHelp() {
	console.log(`
Musea VRT - Visual Regression Testing for Component Gallery

Usage:
  musea-vrt [command] [options]

Commands:
  (default)             Run VRT tests
  approve [pattern]     Approve failed snapshots and update baselines
                        Optional pattern filters which snapshots to approve
  clean                 Remove orphaned snapshots (no matching art/variant)
  generate <component>  Auto-generate .art.vue from a Vue component

Options:
  -u, --update         Update baseline snapshots with current screenshots
  -c, --config <path>  Path to vite config file (default: vite.config.ts)
  -o, --output <dir>   Output directory for reports (default: .vize)
  -t, --threshold <n>  Diff threshold percentage (default: 0.1)
  -b, --base-url <url> Base URL for dev server (default: http://localhost:5173)
  --json               Output JSON report instead of HTML
  --ci                 CI mode - exit with non-zero code on failures
  --a11y               Run accessibility audits alongside VRT
  -h, --help           Show this help message

Examples:
  # Run VRT tests
  musea-vrt

  # Update baseline snapshots
  musea-vrt -u

  # Run with custom threshold
  musea-vrt -t 0.5

  # CI mode with JSON output
  musea-vrt --ci --json

  # Run with accessibility audits
  musea-vrt --a11y

  # Approve all failed snapshots
  musea-vrt approve

  # Approve specific snapshots by pattern
  musea-vrt approve "Button/*"

  # Clean orphaned snapshots
  musea-vrt clean

  # Auto-generate .art.vue from component
  musea-vrt generate src/components/Button.vue

  # Custom base URL
  musea-vrt -b http://localhost:3000
`);
}
async function main() {
	const options = parseArgs(process.argv.slice(2));
	if (options.help) {
		printHelp();
		process.exit(0);
	}
	const cwd = process.cwd();
	console.log("\n  Musea VRT");
	console.log("  =========\n");
	if (options.command === "generate") {
		try {
			await runGenerate(options);
		} catch (error) {
			console.error("\n  Error:", error);
			process.exit(1);
		}
		return;
	}
	console.log("  Scanning for art files...");
	const artFilePaths = await scanArtFiles(cwd);
	if (artFilePaths.length === 0) {
		console.log("  No art files found.\n");
		process.exit(0);
	}
	console.log(`  Found ${artFilePaths.length} art file(s)\n`);
	const artFiles = [];
	for (const filePath of artFilePaths) {
		const art = await parseArtFile(filePath);
		if (art) artFiles.push(art);
	}
	try {
		switch (options.command) {
			case "run":
				await runVrt(options, artFiles);
				break;
			case "approve":
				await runApprove(options, artFiles);
				break;
			case "clean":
				await runClean(options, artFiles);
				break;
			case "generate": break;
		}
	} catch (error) {
		console.error("\n  Error:", error);
		process.exit(1);
	}
}
main().catch((error) => {
	console.error("Fatal error:", error);
	process.exit(1);
});
//#endregion
export {};

//# sourceMappingURL=index.mjs.map