//===---- ParserTests.cpp -------------------------------------------------===//
//
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
//===----------------------------------------------------------------------===//

#include "macro-parser.h"
#include "gtest/gtest.h"

#include "DiffUtils.h"

using namespace goBackendUnitTests;

namespace {

void parseMacros(MacroParser &parser, const char *input)
{
  // Feed lines from the input to the parser, skipping blanks
  assert(input != nullptr);
  std::stringstream ss(input);
  std::string line;
  unsigned lno = 1;
  while (std::getline(ss,line,'\n')) {
    if (line.empty())
      continue;
    auto fne = line.find_first_not_of(" \t");
    if (fne == std::string::npos)
      continue;
    parser.visitMacroLine(line.substr(fne), lno++);
  }
}

std::string postProcessAndEmit(MacroParser &parser)
{
  // Post-process
  parser.postProcessMacros();

  // Emit result to a string and return
  std::string result;
  llvm::raw_string_ostream os(result);
  std::unordered_set<std::string> empty;
  parser.emitMacros(os, empty);
  return os.str();
}

std::string processMacros(const char *input)
{
  MacroParser parser;
  parseMacros(parser, input);
  return postProcessAndEmit(parser);
}

bool expectEqualTokens(const std::string &actual, const ExpectedDump &ed)
{
  const std::string &expected = ed.content;
  std::string reason;
  bool equal = difftokens(expected, actual, reason);
  if (! equal)
    complainOnNequal(reason, ed, actual);
  return equal;
}

TEST(GoDumpSpecParserTests, BasicParser) {

  const char *input = R"RAW_INPUT(
    #define FOO BAR
    #define BLIX
    #define BAR 10
    )RAW_INPUT";
  EXPECT_TRUE(true);

  std::string result = processMacros(input);

  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
    const _BAR = 10
    const _FOO = _BAR
    )RAW_RESULT");

  EXPECT_TRUE(expectEqualTokens(result, exp));
}

TEST(GoDumpSpecParserTests, MacroDefCycle) {

  const char *input = R"RAW_INPUT(
    #define FOO BAR
    #define BLIX "hello world"
    #define BAR FOO
    )RAW_INPUT";
  EXPECT_TRUE(true);

  std::string result = processMacros(input);

  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
    const _BLIX = "hello world"
    )RAW_RESULT");

  EXPECT_TRUE(expectEqualTokens(result, exp));
}

TEST(GoDumpSpecParserTests, FunctionMacros) {

  const char *input = R"RAW_INPUT(
    #define ISFUNC() 99
    #define FOO(x,y) x+y
    #define BLIX (7.8e-2*9.01e-8+.00001)<<4u
    #define GLIX() FOO(3,4)
    )RAW_INPUT";
  EXPECT_TRUE(true);

  std::string result = processMacros(input);

  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
    const _BLIX = (7.8e-2*9.01e-8+.00001)<<4
    )RAW_RESULT");

  EXPECT_TRUE(expectEqualTokens(result, exp));
}

TEST(GoDumpSpecParserTests, BadStringLiterals) {

  const char *input = R"RAW_INPUT(
    #define BAD1 '\0'
    #define BAD2 "ok up until this: \0 "
    #define BAD3 '\xa'
    #define GOOD ""
    )RAW_INPUT";
  EXPECT_TRUE(true);

  std::string result = processMacros(input);

  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
    const _GOOD = ""
    )RAW_RESULT");

  EXPECT_TRUE(expectEqualTokens(result, exp));
}

TEST(GoDumpSpecParserTests, EmptyMacros) {

  const char *input = R"RAW_INPUT(
    #define EMPTY1
    #define EMPTY2 EMPTY1
    #define EMPTY3 EMPTY2 EMPTY1
    #define BAD (1+2)<<
    #define GOOD (1+2)<<9
    )RAW_INPUT";
  EXPECT_TRUE(true);

  std::string result = processMacros(input);

  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
    const _GOOD = (1+2)<<9
    )RAW_RESULT");

  EXPECT_TRUE(expectEqualTokens(result, exp));
}

TEST(GoDumpSpecParserTests, MacrosAndEnums) {

  const char *input = R"RAW_INPUT(
    #define E1 10
    #define E2 (EX + E1)
    #define EX "ignored"
    )RAW_INPUT";
  EXPECT_TRUE(true);

  MacroParser parser;

  // Register enum
  parser.addEnumLiteralPseudoMacro("EX", "9");

  // Now digest macros
  parseMacros(parser, input);

  std::string result = postProcessAndEmit(parser);

  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
    const _E1 = 10
    const _E2 = (_EX + _E1)
    const _EX = 9
    )RAW_RESULT");

  EXPECT_TRUE(expectEqualTokens(result, exp));
}

} // namespace
