// 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 "absl/strings/string_view.h"
#include "common/analysis/matcher/descent_path.h"
#include "common/text/parser_verifier.h"
#include "common/text/symbol.h"
#include "common/text/token_info_test_util.h"
#include "common/util/logging.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_
