// 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 "gtest/gtest.h"
#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"

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(const std::string& 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(const std::string& code, int i) {
  VLOG(1) << "test_data[" << i << "] = '" << code << "'\n";

  AnalyzerType analyzer(code, "<<inline-test>>");
  absl::Status status = analyzer.Analyze();
  EXPECT_TRUE(status.ok());

  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_
