// Build Configuration Parser
// Handles CLI/build config overrides for libraries and stack

import * as yaml from 'js-yaml';
import { readFileSync } from 'fs';

export interface BuildConfig {
  version: number;
  type: string;
  
  // Stack configuration - ONLY non-UI components allowed
  stack?: {
    frontend: 'react' | 'vue' | 'svelte';
    state_management: 'redux' | 'mobx' | 'zustand' | 'context';
    api_client: 'axios' | 'fetch' | 'graphql-request' | 'apollo';
    build_tool: 'vite' | 'webpack' | 'next' | 'rollup';
  };
  
  // Backend integration
  backend?: {
    provider: 'wundergraph' | 'graphql' | 'rest' | 'firebase' | 'supabase';
    endpoint?: string;
    auth_required?: boolean;
  };
  
  // Routing configuration
  routing?: {
    strategy: 'file-based' | 'config-based';
    nested_routes?: boolean;
    dynamic_routes?: boolean;
  };
}

export class BuildConfigParser {
  /**
   * Parse a YAML file containing build configuration
   * @param filePath Path to the YAML file
   * @returns Parsed build configuration
   */
  static parseConfig(filePath: string): BuildConfig {
    try {
      const fileContent = readFileSync(filePath, 'utf8');
      const parsed = yaml.load(fileContent) as BuildConfig;
      
      // Validate required fields
      if (!parsed.version) {
        throw new Error('Missing required field: version');
      }
      
      if (!parsed.type) {
        throw new Error('Missing required field: type');
      }
      
      return parsed;
    } catch (error) {
      throw new Error(`Failed to parse build config YAML file ${filePath}: ${(error as Error).message}`);
    }
  }
  
  /**
   * Get the effective component library for a specific component
   * @param config Build configuration
   * @param componentName Name of the component
   * @returns The effective library for the component
   */
  static getComponentLibrary(): string {
    return "aceternity"; // Default to Aceternity UI for now
  }
  
  /**
   * Get the effective stack configuration
   * @param config Build configuration
   * @returns The effective stack configuration
   */
  static getStackConfig(config: BuildConfig): BuildConfig['stack'] {
    // Return stack config if specified, otherwise default values
    return config.stack || {
      frontend: 'react',
      state_management: 'redux',
      api_client: 'axios',
      build_tool: 'vite'
    };
  }
  
  /**
   * Get the effective backend configuration
   * @param config Build configuration
   * @returns The effective backend configuration
   */
  static getBackendConfig(config: BuildConfig): BuildConfig['backend'] {
    // Return backend config if specified
    return config.backend;
  }
  
  /**
   * Get the effective routing configuration
   * @param config Build configuration
   * @returns The effective routing configuration
   */
  static getRoutingConfig(config: BuildConfig): BuildConfig['routing'] {
    // Return routing config if specified, otherwise default values
    return config.routing || {
      strategy: 'file-based',
      nested_routes: true,
      dynamic_routes: true
    };
  }
  
  /**
   * Validate build configuration compatibility
   * @param config Build configuration
   * @returns Validation result with isValid flag and errors array
   */
  static validateConfig(config: BuildConfig): { 
    isValid: boolean; 
    errors: string[] 
  } {
    const errors: string[] = [];
    
    // Validate stack configuration
    if (config.stack) {
      const validFrontends = ['react', 'vue', 'svelte'];
      const validStateManagement = ['redux', 'mobx', 'zustand', 'context'];
      const validApiClient = ['axios', 'fetch', 'graphql-request', 'apollo'];
      const validBuildTools = ['vite', 'webpack', 'next', 'rollup'];
      
      if (config.stack.frontend && !validFrontends.includes(config.stack.frontend)) {
        errors.push(`Invalid frontend: ${config.stack.frontend}`);
      }
      
      if (config.stack.state_management && !validStateManagement.includes(config.stack.state_management)) {
        errors.push(`Invalid state management: ${config.stack.state_management}`);
      }
      
      if (config.stack.api_client && !validApiClient.includes(config.stack.api_client)) {
        errors.push(`Invalid API client: ${config.stack.api_client}`);
      }
      
      if (config.stack.build_tool && !validBuildTools.includes(config.stack.build_tool)) {
        errors.push(`Invalid build tool: ${config.stack.build_tool}`);
      }
    }
    
    // Validate backend configuration
    if (config.backend) {
      const validProviders = ['wundergraph', 'graphql', 'rest', 'firebase', 'supabase'];
      
      if (config.backend.provider && !validProviders.includes(config.backend.provider)) {
        errors.push(`Invalid backend provider: ${config.backend.provider}`);
      }
      
      if (config.backend.auth_required && typeof config.backend.auth_required !== 'boolean') {
        errors.push('auth_required must be a boolean');
      }
    }
    
    // Validate routing configuration
    if (config.routing) {
      const validStrategies = ['file-based', 'config-based'];
      
      if (config.routing.strategy && !validStrategies.includes(config.routing.strategy)) {
        errors.push(`Invalid routing strategy: ${config.routing.strategy}`);
      }
      
      if (config.routing.nested_routes && typeof config.routing.nested_routes !== 'boolean') {
        errors.push('nested_routes must be a boolean');
      }
      
      if (config.routing.dynamic_routes && typeof config.routing.dynamic_routes !== 'boolean') {
        errors.push('dynamic_routes must be a boolean');
      }
    }
    
    return {
      isValid: errors.length === 0,
      errors
    };
  }
}

// Utility functions for common config tasks
export const parseBuildConfig = (filePath: string) => BuildConfigParser.parseConfig(filePath);
export const validateBuildConfig = (config: BuildConfig) => BuildConfigParser.validateConfig(config);
export const getComponentLibrary = () => BuildConfigParser.getComponentLibrary();
export const getStackConfig = (config: BuildConfig) => BuildConfigParser.getStackConfig(config);
export const getBackendConfig = (config: BuildConfig) => BuildConfigParser.getBackendConfig(config);
export const getRoutingConfig = (config: BuildConfig) => BuildConfigParser.getRoutingConfig(config);
