// 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.

// Utility functions for parser testing.

#ifndef VERIBLE_COMMON_PARSER_PARSER_TEST_UTIL_H_
#define VERIBLE_COMMON_PARSER_PARSER_TEST_UTIL_H_

#include <string>  // for string
#include <vector>

#include "absl/status/status.h"
#include "common/analysis/matcher/descent_path.h"
#include "common/text/parser_verifier.h"
#include "common/text/symbol.h"
#include "common/text/token_info.h"
#include "common/text/token_info_test_util.h"
#include "gtest/gtest.h"

namespace verible {

// Tests the parser on source text that is valid input.
// class AnalyzerType is any class with a absl::Status AnalyzerType::Analyze()
// method.
template <class AnalyzerType>
void TestParserAcceptValid(absl::string_view code, int i) {
  VLOG(1) << "test_data[" << i << "] = '" << code << "'\n";
  AnalyzerType analyzer(code, "<<inline-test>>");
  absl::Status status = analyzer.Analyze();
  if (!status.ok()) {
    // Print more detailed error message.
    const auto& rejected_tokens = analyzer.GetRejectedTokens();
    if (!rejected_tokens.empty()) {
      EXPECT_TRUE(status.ok())
          << "Rejected valid code:\n"
          << code << "\nRejected token: " << rejected_tokens[0].token_info;
    } else {
      EXPECT_TRUE(status.ok()) << "Rejected valid code:\n" << code;
    }
  }
  EXPECT_TRUE(analyzer.SyntaxTree().get()) << "Missing tree on code:\n" << code;
}

// Tests the parser on source text that is invalid input.
// class AnalyzerType is any class with a absl::Status AnalyzerType::Analyze()
// method.
template <class AnalyzerType>
void TestParserRejectInvalid(const TokenInfoTestData& test, int i) {
  VLOG(1) << "test_data[" << i << "] = '" << test.code << "'\n";
  ASSERT_FALSE(test.expected_tokens.empty());
  // Find the first not-don't-care token.
  int iteration = 0;
  do {
    AnalyzerType analyzer(test.code, "<<inline-test>>");  // copies code
    const absl::Status status = analyzer.Analyze();
    EXPECT_FALSE(status.ok())
        << "Accepted invalid code (iteration: " << iteration << "):\n"
        << test.code;
    const auto& rejected_tokens = analyzer.GetRejectedTokens();
    ASSERT_FALSE(rejected_tokens.empty());

    const absl::string_view base_text = analyzer.Data().Contents();
    const auto expected_error_tokens = test.FindImportantTokens(base_text);
    ASSERT_FALSE(expected_error_tokens.empty());
    // Only check the first rejected token, ignore the rest.
    const auto& expected_error_token = expected_error_tokens.front();
    EXPECT_EQ(expected_error_token, rejected_tokens[0].token_info);
    ++iteration;
    // Run the analyzer a second time to make sure the parser cleared
    // away any state, and finds the same error.
  } while (iteration < 2);
}

struct ErrorRecoveryTestCase {
  // Code containing a syntax error.
  std::string code;
  // Node path that is expected to exist due to error-recovery.
  // TODO(b/64093049): generalize to use AST matcher classes.
  matcher::DescentPath tree_path;
};

template <class AnalyzerType>
void TestParserErrorRecovered(const ErrorRecoveryTestCase& test, int i) {
  VLOG(1) << "test_data[" << i << "] = '" << test.code << "'\n";
  int iteration = 0;
  do {
    AnalyzerType analyzer(test.code, "<<inline-test>>");
    absl::Status status = analyzer.Analyze();
    EXPECT_FALSE(status.ok())
        << "Accepted invalid code (iteration: " << iteration << "):\n"
        << test.code;
    const auto rejected_tokens = analyzer.GetRejectedTokens();
    EXPECT_FALSE(rejected_tokens.empty());
    // Only check the first rejected token, ignore the rest.
    const auto& tree = analyzer.SyntaxTree();
    const auto matching_paths = matcher::GetAllDescendantsFromPath(
        *ABSL_DIE_IF_NULL(tree), test.tree_path);
    EXPECT_FALSE(matching_paths.empty())
        << "Expected tree path not found.  code:\n"
        << test.code;
    ++iteration;
    // Run the analyzer a second time to make sure the parser cleared
    // away any state, and produces the same result.
  } while (iteration < 2);
}

template <class AnalyzerType>
void TestParserAllMatched(absl::string_view code, int i) {
  VLOG(1) << "test_data[" << i << "] = '" << code << "'\n";

  AnalyzerType analyzer(code, "<<inline-test>>");
  absl::Status status = analyzer.Analyze();
  EXPECT_TRUE(status.ok()) << status.message() << "\nRejected: "
                           << analyzer.GetRejectedTokens().front().token_info;

  const Symbol* tree_ptr = analyzer.SyntaxTree().get();
  EXPECT_NE(tree_ptr, nullptr) << "Missing syntax tree with input:\n" << code;
  if (tree_ptr == nullptr) return;  // Already failed, abort this test case.
  const Symbol& root = *tree_ptr;

  ParserVerifier verifier(root, analyzer.Data().GetTokenStreamView());
  const auto unmatched = verifier.Verify();

  EXPECT_EQ(unmatched.size(), 0)
      << "On code:\n"
      << code << "\nFirst unmatched token: " << unmatched.front();
}

}  // namespace verible

#endif  // VERIBLE_COMMON_PARSER_PARSER_TEST_UTIL_H_
