/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.calcite.runtime;

import org.apache.calcite.rel.core.Match;
import org.apache.calcite.util.ImmutableBitSet;

import com.google.common.collect.ImmutableList;

import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.Objects;

/** A nondeterministic finite-state automaton (NFA).
 *
 * <p>It is used to implement the {@link Match}
 * relational expression (for the {@code MATCH_RECOGNIZE} clause in SQL).
 *
 * @see Pattern
 * @see AutomatonBuilder
 * @see DeterministicAutomaton
 */
public class Automaton {
  final State startState;
  final State endState;
  private final ImmutableList<SymbolTransition> transitions;
  private final ImmutableList<EpsilonTransition> epsilonTransitions;
  final ImmutableList<String> symbolNames;

  /** Use an {@link AutomatonBuilder}. */
  Automaton(State startState, State endState,
      ImmutableList<SymbolTransition> transitions,
      ImmutableList<EpsilonTransition> epsilonTransitions,
      ImmutableList<String> symbolNames) {
    this.startState = Objects.requireNonNull(startState, "startState");
    this.endState = Objects.requireNonNull(endState, "endState");
    this.transitions = Objects.requireNonNull(transitions, "transitions");
    this.epsilonTransitions = epsilonTransitions;
    this.symbolNames = Objects.requireNonNull(symbolNames, "symbolNames");
  }

  /** Returns the set of states, represented as a bit set, that the graph is
   * in when starting from {@code state} and receiving {@code symbol}.
   *
   * @param fromState Initial state
   * @param symbol Symbol received
   * @param bitSet Set of successor states (output)
   */
  void successors(int fromState, int symbol,
      ImmutableBitSet.Builder bitSet) {
    for (SymbolTransition transition : transitions) {
      if (transition.fromState.id == fromState
          && transition.symbol == symbol) {
        epsilonSuccessors(transition.toState.id, bitSet);
      }
    }
  }

  void epsilonSuccessors(int state, ImmutableBitSet.Builder bitSet) {
    bitSet.set(state);
    for (EpsilonTransition transition : epsilonTransitions) {
      if (transition.fromState.id == state) {
        if (!bitSet.get(transition.toState.id)) {
          epsilonSuccessors(transition.toState.id, bitSet);
        }
      }
    }
  }

  public ImmutableList<SymbolTransition> getTransitions() {
    return this.transitions;
  }

  public ImmutableList<EpsilonTransition> getEpsilonTransitions() {
    return this.epsilonTransitions;
  }

  /** Node in the finite-state automaton. A state has a number of
   * transitions to other states, each labeled with the symbol that
   * causes that transition. */
  static class State {
    final int id;

    State(int id) {
      this.id = id;
    }

    @Override public boolean equals(@Nullable Object o) {
      return o == this
          || o instanceof State
          && ((State) o).id == id;
    }

    @Override public int hashCode() {
      return Objects.hash(id);
    }

    @Override public String toString() {
      return "State{"
          + "id=" + id
          + '}';
    }
  }

  /** Transition from one state to another in the finite-state automaton. */
  abstract static class Transition {
    final State fromState;
    final State toState;

    Transition(State fromState, State toState) {
      this.fromState = Objects.requireNonNull(fromState, "fromState");
      this.toState = Objects.requireNonNull(toState, "toState");
    }
  }

  /** A transition caused by reading a symbol. */
  static class SymbolTransition extends Transition {
    final int symbol;

    SymbolTransition(State fromState, State toState, int symbol) {
      super(fromState, toState);
      this.symbol = symbol;
    }

    @Override public String toString() {
      return symbol + ":" + fromState.id + "->" + toState.id;
    }
  }

  /** A transition that may happen without reading a symbol. */
  static class EpsilonTransition extends Transition {
    EpsilonTransition(State fromState, State toState) {
      super(fromState, toState);
    }

    @Override public String toString() {
      return "epsilon:" + fromState.id + "->" + toState.id;
    }
  }
}
