// Copyright 2017-2020 The Verible Authors.
//
// Licensed 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.

#include <vector>

#include "common/analysis/matcher/bound_symbol_manager.h"
#include "common/analysis/matcher/matcher.h"
#include "common/text/symbol.h"
#include "common/util/logging.h"

namespace verible {
namespace matcher {

bool InnerMatchAll(const Symbol& symbol,
                   const std::vector<Matcher>& inner_matchers,
                   BoundSymbolManager* manager) {
  BoundSymbolManager backtrack_checkpoint(*manager);

  for (const auto& matcher : inner_matchers) {
    if (!matcher.Matches(symbol, manager)) {
      *manager = backtrack_checkpoint;
      return false;
    }
  }
  return true;
}

bool InnerMatchAny(const Symbol& symbol,
                   const std::vector<Matcher>& inner_matchers,
                   BoundSymbolManager* manager) {
  for (const auto& matcher : inner_matchers) {
    BoundSymbolManager lookahead(*manager);
    if (matcher.Matches(symbol, &lookahead)) {
      *manager = lookahead;
      return true;
    }
  }
  return false;
}

bool InnerMatchEachOf(const Symbol& symbol,
                      const std::vector<Matcher>& inner_matchers,
                      BoundSymbolManager* manager) {
  bool some_inner_matched_passed = false;

  for (const auto& matcher : inner_matchers) {
    BoundSymbolManager backup(*manager);
    if (matcher.Matches(symbol, manager)) {
      // If matcher passes, remember that we found a passing inner matcher
      some_inner_matched_passed = true;
    } else {
      // If failed to match, revert manager to backup.
      *manager = backup;
    }
  }

  return some_inner_matched_passed;
}

bool InnerMatchUnless(const Symbol& symbol,
                      const std::vector<Matcher>& inner_matchers,
                      BoundSymbolManager* manager) {
  CHECK_EQ(inner_matchers.size(), 1);

  const auto& matcher = inner_matchers[0];

  // We don't need to keep track of what inner matcher matches because any
  // binds will be discarded if it matches.
  BoundSymbolManager dummy_manager;

  return !matcher.Matches(symbol, &dummy_manager);
}

}  // namespace matcher
}  // namespace verible
