import * as GeneratedParser from './GeneratedParser.js';

/**
 * Peggy-based DSL Parser
 * Uses the generated parser from Peggy grammar
 */
export class PeggyDSLParser {
  constructor() {
    this.parser = GeneratedParser;
    this.errors = [];
  }

  /**
   * Parse DSL text into AST
   * @param {string} dslText - DSL text to parse
   * @returns {ProgramNode} Parsed AST
   */
  parse(dslText) {
    this.errors = [];
    
    try {
      const program = this.parser.parse(dslText);
      return program;
    } catch (error) {
      this.errors.push(`Parse error: ${error.message}`);
      
      // If the error has location information, add it to the error
      if (error.location) {
        const location = error.location;
        this.errors.push(`Location: line ${location.start.line}, column ${location.start.column}`);
      }
      
      // If the error has expected/found information, add it
      if (error.expected && error.found) {
        this.errors.push(`Expected: ${error.expected.join(', ')}`);
        this.errors.push(`Found: ${error.found}`);
      }
      
      throw new Error(`Parsing failed: ${this.errors.join('; ')}`);
    }
  }

  /**
   * Get parser errors from last parse
   * @returns {string[]} Array of parser errors
   */
  getErrors() {
    return this.errors;
  }

  /**
   * Validate DSL text without throwing errors
   * @param {string} dslText - DSL text to validate
   * @returns {Object} Validation result with success status and errors
   */
  validate(dslText) {
    try {
      const program = this.parse(dslText);
      return {
        success: true,
        errors: [],
        program: program
      };
    } catch (error) {
      return {
        success: false,
        errors: this.errors,
        program: null
      };
    }
  }

  /**
   * Parse with options
   * @param {string} dslText - DSL text to parse
   * @param {Object} options - Parser options
   * @returns {ProgramNode} Parsed AST
   */
  parseWithOptions(dslText, options = {}) {
    this.errors = [];
    
    try {
      const program = this.parser.parse(dslText, options);
      return program;
    } catch (error) {
      this.errors.push(`Parse error: ${error.message}`);
      
      if (error.location) {
        const location = error.location;
        this.errors.push(`Location: line ${location.start.line}, column ${location.start.column}`);
      }
      
      if (error.expected && error.found) {
        this.errors.push(`Expected: ${error.expected.join(', ')}`);
        this.errors.push(`Found: ${error.found}`);
      }
      
      throw new Error(`Parsing failed: ${this.errors.join('; ')}`);
    }
  }

  /**
   * Get parser information
   * @returns {Object} Parser information
   */
  getParserInfo() {
    return {
      name: 'PeggyDSLParser',
      version: '1.0.0',
      generated: true,
      grammar: 'dsl.peggy'
    };
  }
}
