import { BaseNode } from './BaseNode.js';

/**
 * AST node for measure body containing expressions
 * Represents: { user.role }
 */
export class MeasureBodyNode extends BaseNode {
  constructor(location = null) {
    super('MeasureBody', location);
    this.expression = null; // ExpressionNode
    this.fusion = null; // FusionNode (optional)
    this.aggregation = null; // AggregationNode (optional)
  }

  /**
   * Set the expression for this measure body
   * @param {ExpressionNode} expression - Expression to set
   */
  setExpression(expression) {
    this.expression = expression;
    this.addChild(expression);
  }

  /**
   * Set the fusion for this measure body
   * @param {FusionNode} fusion - Fusion to set
   */
  setFusion(fusion) {
    this.fusion = fusion;
    this.addChild(fusion);
  }

  /**
   * Set the aggregation for this measure body
   * @param {AggregationNode} aggregation - Aggregation to set
   */
  setAggregation(aggregation) {
    this.aggregation = aggregation;
    this.addChild(aggregation);
  }

  /**
   * Get the expression
   * @returns {ExpressionNode|null} Expression or null
   */
  getExpression() {
    return this.expression;
  }

  /**
   * Get the fusion
   * @returns {FusionNode|null} Fusion or null
   */
  getFusion() {
    return this.fusion;
  }

  /**
   * Get the aggregation
   * @returns {AggregationNode|null} Aggregation or null
   */
  getAggregation() {
    return this.aggregation;
  }

  /**
   * Check if this measure body has an expression
   * @returns {boolean} True if has expression
   */
  hasExpression() {
    return this.expression !== null;
  }

  /**
   * Check if this measure body has fusion
   * @returns {boolean} True if has fusion
   */
  hasFusion() {
    return this.fusion !== null;
  }

  /**
   * Check if this measure body has aggregation
   * @returns {boolean} True if has aggregation
   */
  hasAggregation() {
    return this.aggregation !== null;
  }

  /**
   * Validate the measure body
   * @returns {string[]} Array of error messages
   */
  validate() {
    const errors = [];

    // Must have at least one of expression, fusion, or aggregation
    if (!this.expression && !this.fusion && !this.aggregation) {
      errors.push('Measure body must have an expression, fusion, or aggregation');
    }

    // Validate expression if present
    if (this.expression) {
      const exprErrors = this.expression.validate ? this.expression.validate() : [];
      errors.push(...exprErrors);
    }

    // Validate fusion if present
    if (this.fusion) {
      const fusionErrors = this.fusion.validate ? this.fusion.validate() : [];
      errors.push(...fusionErrors);
    }

    // Validate aggregation if present
    if (this.aggregation) {
      const aggErrors = this.aggregation.validate ? this.aggregation.validate() : [];
      errors.push(...aggErrors);
    }

    return errors;
  }

  toString() {
    const parts = [];
    if (this.expression) parts.push(this.expression.toString());
    if (this.fusion) parts.push(this.fusion.toString());
    if (this.aggregation) parts.push(this.aggregation.toString());
    return `MeasureBody(${parts.join(', ')})`;
  }
}
