/**
 * Main Validator
 *
 * Orchestrates manifest and installation validation.
 * Provides a unified interface for validating SpecVerse projects.
 *
 * @module registry/validators/validator
 * @version 2.0.0
 */
import { ManifestValidator } from './manifest-validator.js';
import { InstallationValidator } from './installation-validator.js';
import { OfflineHandler } from '../offline/offline-handler.js';
import { mergeResults } from '../types/index.js';
/**
 * Main Validator
 *
 * Orchestrates all validation stages.
 */
export class Validator {
    manifestValidator;
    installationValidator;
    offlineHandler;
    constructor(offlineHandler) {
        this.offlineHandler = offlineHandler || new OfflineHandler();
        this.manifestValidator = new ManifestValidator(this.offlineHandler);
        this.installationValidator = new InstallationValidator();
    }
    /**
     * Validate a manifest file
     *
     * Runs both manifest and installation validation unless skipped.
     *
     * @param manifest - Manifest to validate
     * @param options - Validation options
     * @returns Validation report
     */
    async validate(manifest, options = {}) {
        const validationsPassed = [];
        const validationsFailed = [];
        let manifestResult;
        let installationResult;
        // Stage 1: Manifest Validation (unless skipped)
        if (!options.skipManifest) {
            const manifestOptions = {
                ...options.manifest,
                offline: options.offline
            };
            manifestResult = await this.manifestValidator.validate(manifest, manifestOptions);
            if (manifestResult.valid) {
                validationsPassed.push('manifest');
            }
            else {
                validationsFailed.push('manifest');
            }
        }
        // Stage 2: Installation Validation (unless skipped or manifest failed critically)
        if (!options.skipInstallation) {
            // Only run installation validation if we have manifest data or skipped manifest
            if (options.skipManifest || !manifestResult || manifestResult.valid) {
                // Get registry factories from offline handler
                const registryResult = await this.offlineHandler.fetchFactories();
                const registryFactories = new Map(registryResult.data.results.map(f => [f.name, f]));
                installationResult = await this.installationValidator.validate(manifest, registryFactories, options.installation);
                if (installationResult.valid) {
                    validationsPassed.push('installation');
                }
                else {
                    validationsFailed.push('installation');
                }
            }
            else {
                // Skip installation validation if manifest failed
                validationsFailed.push('installation (skipped due to manifest errors)');
            }
        }
        // Merge results
        const results = [manifestResult, installationResult].filter((r) => r !== undefined);
        const mergedResult = results.length > 0
            ? mergeResults(...results)
            : {
                valid: true,
                errors: [],
                warnings: [],
                info: []
            };
        return {
            result: mergedResult,
            manifestResult,
            installationResult,
            summary: {
                totalIssues: mergedResult.errors.length +
                    mergedResult.warnings.length +
                    mergedResult.info.length,
                errorCount: mergedResult.errors.length,
                warningCount: mergedResult.warnings.length,
                infoCount: mergedResult.info.length,
                validationsPassed,
                validationsFailed
            }
        };
    }
    /**
     * Validate manifest only (skip installation check)
     *
     * @param manifest - Manifest to validate
     * @param options - Manifest validation options
     * @returns Validation report
     */
    async validateManifestOnly(manifest, options) {
        return this.validate(manifest, {
            manifest: options,
            skipInstallation: true
        });
    }
    /**
     * Validate installation only (skip manifest check)
     *
     * @param manifest - Manifest to validate
     * @param options - Installation validation options
     * @returns Validation report
     */
    async validateInstallationOnly(manifest, options) {
        return this.validate(manifest, {
            installation: options,
            skipManifest: true
        });
    }
    /**
     * Get offline handler
     *
     * @returns Offline handler instance
     */
    getOfflineHandler() {
        return this.offlineHandler;
    }
    /**
     * Get manifest validator
     *
     * @returns Manifest validator instance
     */
    getManifestValidator() {
        return this.manifestValidator;
    }
    /**
     * Get installation validator
     *
     * @returns Installation validator instance
     */
    getInstallationValidator() {
        return this.installationValidator;
    }
    /**
     * Enable offline mode
     */
    enableOfflineMode() {
        this.offlineHandler.enableOfflineMode();
    }
    /**
     * Disable offline mode
     */
    disableOfflineMode() {
        this.offlineHandler.disableOfflineMode();
    }
}
//# sourceMappingURL=validator.js.map