package org.petitparser.parser.repeating;

import org.petitparser.parser.Parser;
import org.petitparser.parser.combinators.DelegateParser;

import java.util.Objects;

/**
 * An abstract parser that repeatedly parses between 'min' and 'max' instances
 * of its delegate.
 */
public abstract class RepeatingParser extends DelegateParser {

  public static final int UNBOUNDED = -1;

  protected final int min;
  protected final int max;

  public RepeatingParser(Parser delegate, int min, int max) {
    super(delegate);
    this.min = min;
    this.max = max;
    if (min < 0) {
      throw new IllegalArgumentException(
          "Invalid min repetitions: " + getRange());
    }
    if (max != UNBOUNDED && min > max) {
      throw new IllegalArgumentException(
          "Invalid max repetitions: " + getRange());
    }
  }

  @Override
  public boolean hasEqualProperties(Parser other) {
    return super.hasEqualProperties(other) &&
        Objects.equals(min, ((RepeatingParser) other).min) &&
        Objects.equals(max, ((RepeatingParser) other).max);
  }

  @Override
  public String toString() {
    return super.toString() + "[" + getRange() + "]";
  }

  private String getRange() {
    return min + ".." + (max == UNBOUNDED ? "*" : max);
  }
}
