"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DesignTokenService = void 0;
const TailwindCSSTokenAdapter_1 = require("./adapters/TailwindCSSTokenAdapter");
const TailwindTokenAdapter_1 = require("./adapters/TailwindTokenAdapter");
const logger_1 = require("../utils/logger");
const log = (0, logger_1.createLogger)('DesignTokenService');
/**
 * Service for detecting and extracting design tokens from various CSS frameworks.
 * Orchestrates token adapters and provides caching.
 */
class DesignTokenService {
    adapters = [];
    cache = new Map();
    constructor() {
        // v4 adapter listed first so it wins detection for v4 projects
        this.adapters = [new TailwindCSSTokenAdapter_1.TailwindCSSTokenAdapter(), new TailwindTokenAdapter_1.TailwindTokenAdapter()];
    }
    /**
     * Detects and extracts design tokens from the project.
     * Returns cached result if available.
     *
     * @param projectRoot - Root directory of the project
     * @param styleFrameworkOverride - Optional framework override to skip detection
     * @param configPath - Optional explicit path to config file (e.g., landing/tailwind.config.ts)
     * @returns Token registry and framework name, or null if no tokens found
     */
    extractTokens(projectRoot, styleFrameworkOverride, configPath) {
        // Check cache first
        const cached = this.cache.get(projectRoot);
        if (cached) {
            log.debug('Returning cached tokens');
            return cached;
        }
        // Determine which adapter to use
        let adapterToUse = null;
        if (styleFrameworkOverride) {
            // Filter to matching adapters, then pick the one that detects the project
            const matchingAdapters = this.adapters.filter((a) => a.getFramework() === styleFrameworkOverride);
            adapterToUse =
                matchingAdapters.find((a) => a.detect(projectRoot)) || null;
            if (adapterToUse) {
                log.info(`Using ${styleFrameworkOverride} tokens (CLI override)`);
            }
        }
        else {
            // Auto-detect
            adapterToUse = this.adapters.find((a) => a.detect(projectRoot)) || null;
            if (adapterToUse) {
                log.info(`Detected ${adapterToUse.getFramework()} tokens`);
            }
        }
        if (!adapterToUse) {
            log.info('No design tokens found in project');
            return null;
        }
        // Extract tokens
        const registry = adapterToUse.extract(projectRoot, configPath);
        if (!registry) {
            return null;
        }
        const result = {
            registry,
            framework: adapterToUse.getFramework(),
        };
        // Cache the result
        this.cache.set(projectRoot, result);
        log.info(`Extracted tokens: ${this.summarizeRegistry(registry)}`);
        return result;
    }
    /**
     * Invalidates the cache for a specific project.
     * Should be called when token configuration files change.
     *
     * @param projectRoot - Root directory of the project
     */
    invalidateCache(projectRoot) {
        this.cache.delete(projectRoot);
        log.debug(`Cache invalidated for ${projectRoot}`);
    }
    /**
     * Clears all cached token data
     */
    clearCache() {
        this.cache.clear();
        log.debug('All token cache cleared');
    }
    /**
     * Creates a summary of the token registry for logging
     */
    summarizeRegistry(registry) {
        const counts = Object.entries(registry).map(([category, tokens]) => {
            const count = Object.keys(tokens).length;
            return count > 0 ? `${count} ${category}` : null;
        });
        return counts.filter(Boolean).join(', ') || 'no tokens';
    }
}
exports.DesignTokenService = DesignTokenService;
//# sourceMappingURL=DesignTokenService.js.map