//===- llvm/unittests/Frontend/OpenMPDirectiveNameParserTest.cpp ----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Frontend/OpenMP/DirectiveNameParser.h"
#include "llvm/Frontend/OpenMP/OMP.h"
#include "gtest/gtest.h"

#include <cctype>
#include <sstream>
#include <string>
#include <tuple>
#include <vector>

using namespace llvm;

static const omp::DirectiveNameParser &getParser() {
  static omp::DirectiveNameParser Parser(omp::SourceLanguage::C |
                                         omp::SourceLanguage::Fortran);
  return Parser;
}

static std::vector<std::string> tokenize(StringRef S) {
  std::vector<std::string> Tokens;

  using TokenIterator = std::istream_iterator<std::string>;
  std::string Copy = S.str();
  std::istringstream Stream(Copy);

  for (auto I = TokenIterator(Stream), E = TokenIterator(); I != E; ++I)
    Tokens.push_back(*I);
  return Tokens;
}

static std::string &prepareParamName(std::string &Name) {
  for (size_t I = 0, E = Name.size(); I != E; ++I) {
    // The parameter name must only have alphanumeric characters.
    if (!isalnum(Name[I]))
      Name[I] = 'X';
  }
  return Name;
}

// Test tokenizing.

class Tokenize : public testing::TestWithParam<omp::Directive> {};

static bool isEqual(const SmallVector<StringRef> &A,
                    const std::vector<std::string> &B) {
  if (A.size() != B.size())
    return false;

  for (size_t I = 0, E = A.size(); I != E; ++I) {
    if (A[I] != StringRef(B[I]))
      return false;
  }
  return true;
}

TEST_P(Tokenize, T) {
  omp::Directive DirId = GetParam();
  StringRef Name = omp::getOpenMPDirectiveName(DirId, omp::FallbackVersion);

  SmallVector<StringRef> tokens1 = omp::DirectiveNameParser::tokenize(Name);
  std::vector<std::string> tokens2 = tokenize(Name);
  ASSERT_TRUE(isEqual(tokens1, tokens2));
}

static std::string
getParamName1(const testing::TestParamInfo<Tokenize::ParamType> &Info) {
  omp::Directive DirId = Info.param;
  std::string Name =
      omp::getOpenMPDirectiveName(DirId, omp::FallbackVersion).str();
  return prepareParamName(Name);
}

INSTANTIATE_TEST_SUITE_P(DirectiveNameParserTest, Tokenize,
                         testing::ValuesIn(llvm::enum_seq_inclusive(
                             omp::Directive::First_, omp::Directive::Last_)),
                         getParamName1);

// Test parsing of valid names.

using ValueType = std::tuple<omp::Directive, unsigned>;

class ParseValid : public testing::TestWithParam<ValueType> {};

TEST_P(ParseValid, T) {
  auto [DirId, Version] = GetParam();
  if (DirId == omp::Directive::OMPD_unknown)
    return;

  std::string Name = omp::getOpenMPDirectiveName(DirId, Version).str();

  // Tokenize and parse
  auto &Parser = getParser();
  auto *State = Parser.initial();
  ASSERT_TRUE(State != nullptr);

  std::vector<std::string> Tokens = tokenize(Name);
  for (auto &Tok : Tokens) {
    State = Parser.consume(State, Tok);
    ASSERT_TRUE(State != nullptr);
  }

  ASSERT_EQ(State->Value, DirId);
}

static std::string
getParamName2(const testing::TestParamInfo<ParseValid::ParamType> &Info) {
  auto [DirId, Version] = Info.param;
  std::string Name = omp::getOpenMPDirectiveName(DirId, Version).str() + "v" +
                     std::to_string(Version);
  return prepareParamName(Name);
}

INSTANTIATE_TEST_SUITE_P(
    DirectiveNameParserTest, ParseValid,
    testing::Combine(testing::ValuesIn(llvm::enum_seq_inclusive(
                         omp::Directive::First_, omp::Directive::Last_)),
                     testing::ValuesIn(omp::getOpenMPVersions())),
    getParamName2);

// Test parsing of invalid names

class ParseInvalid : public testing::TestWithParam<std::string> {};

TEST_P(ParseInvalid, T) {
  std::string Name = GetParam();

  auto &Parser = getParser();
  auto *State = Parser.initial();
  ASSERT_TRUE(State != nullptr);

  std::vector<std::string> Tokens = tokenize(Name);
  for (auto &Tok : Tokens)
    State = Parser.consume(State, Tok);

  ASSERT_TRUE(State == nullptr || State->Value == omp::Directive::OMPD_unknown);
}

namespace {
using namespace std;

INSTANTIATE_TEST_SUITE_P(DirectiveNameParserTest, ParseInvalid,
                         testing::Values(
                             // Names that contain invalid tokens
                             "bad"s, "target teams invalid"s,
                             "target sections parallel"s,
                             "target teams distribute parallel for wrong"s,
                             // Valid beginning, but not a complete name
                             "begin declare"s,
                             // Complete name with extra tokens
                             "distribute simd target"s));
} // namespace
