//===---- DriverTests.cpp -------------------------------------------------===//
//
// Copyright 2020 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 <iostream>
#include <map>
#include <set>
#include <stdarg.h>

#include "Driver.h"
#include "Compilation.h"

#include "gtest/gtest.h"

#include "DiffUtils.h"

using namespace llvm;
using namespace gollvm::driver;
using namespace goBackendUnitTests;

namespace {

inline std::vector<const char *> A(const char *arg, ...) {
  va_list ap;
  va_start(ap, arg);
  std::vector<const char *> result;
  while(arg != nullptr) {
    result.push_back(arg);
    arg = va_arg(ap, const char *);
  }
  return result;
}

class DrvTestHarness {
 public:
  explicit DrvTestHarness(const std::vector<const char *> args)
      : args_(args) { }

  // Returns non-zero on error, zero for success.
  unsigned Perform();

  // Test that a dump of driver actions matches the expected result.
  bool expectActions(const ExpectedDump &ed);

 private:
  const std::vector<const char *> args_;
  std::string actionsDump_;
};

unsigned DrvTestHarness::Perform()
{
  std::unique_ptr<opt::OptTable> opts =
      gollvm::options::createGollvmDriverOptTable();
  unsigned missingArgIndex, missingArgCount;
  ArrayRef<const char *> argvv = makeArrayRef(args_);
  opt::InputArgList args =
      opts->ParseArgs(argvv, missingArgIndex, missingArgCount);

  // Complain about missing arguments.
  if (missingArgIndex != 0) {
    errs() << "error: argument to '"
           << args.getArgString(missingArgIndex)
           << "' option missing, expected "
           << missingArgCount << " value(s)\n";
    return 1;
  }

  // Look for unknown options.
  for (const opt::Arg *arg : args.filtered(gollvm::options::OPT_UNKNOWN)) {
    errs() << "error: unrecognized command line option '"
             << arg->getAsString(args) << "'\n";
    return 2;
  }

  // Create driver.
  Driver driver(args, opts.get(), "llvm-goc", true);
  driver.setUnitTesting();

  // Set up driver, select target and toolchain.
  ToolChain *toolchain = driver.setup();
  if (toolchain == nullptr)
    return 1;

  // Build compilation; construct actions for this compile.
  std::unique_ptr<Compilation> compilation =
      driver.buildCompilation(*toolchain);
  if (!driver.buildActions(*compilation))
    return 2;
  if (!driver.processActions(*compilation))
    return 3;
  actionsDump_ = driver.dumpActions(*compilation);
  return 0;
}

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

TEST(DriverTests, SimpleCompile) {
  DrvTestHarness h(A("-c", "foo.go", nullptr));

  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
    Action compile+assemble
      inputs:
        inputfile Artifact arg(foo.go)
      output:
        Artifact file(foo.o)
  )RAW_RESULT");

  unsigned res = h.Perform();
  ASSERT_TRUE(res == 0 && "Setup failed");

  bool isOK = h.expectActions(exp);
  EXPECT_TRUE(isOK && "Actions dump does not have expected contents");
}

TEST(DriverTests, NoIntegAsmCompile) {
  DrvTestHarness h(A("-c", "-fno-integrated-as", "foo.go", nullptr));

  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
    Action compile
      inputs:
        inputfile Artifact arg(foo.go)
      output:
        Artifact file(/tmp/out.compile.0)
    Action assemble
      inputs:
        compile
      output:
        Artifact file(foo.o)
  )RAW_RESULT");

  unsigned res = h.Perform();
  ASSERT_TRUE(res == 0 && "Setup failed");

  bool isOK = h.expectActions(exp);
  EXPECT_TRUE(isOK && "Actions dump does not have expected contents");
}

TEST(DriverTests, CompileToAsm) {
  DrvTestHarness h(A("-S", "foo.go", nullptr));

  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
    Action compile
      inputs:
        inputfile Artifact arg(foo.go)
      output:
        Artifact file(foo.s)
  )RAW_RESULT");

  unsigned res = h.Perform();
  ASSERT_TRUE(res == 0 && "Setup failed");

  bool isOK = h.expectActions(exp);
  EXPECT_TRUE(isOK && "Actions dump does not have expected contents");
}

TEST(DriverTests, CompileToLllvmBitcode) {
  DrvTestHarness h(A("-emit-llvm", "-c", "foo.go", nullptr));

  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
    Action compile
      inputs:
        inputfile Artifact arg(foo.go)
      output:
        Artifact file(foo.bc)
  )RAW_RESULT");

  unsigned res = h.Perform();
  ASSERT_TRUE(res == 0 && "Setup failed");

  bool isOK = h.expectActions(exp);
  EXPECT_TRUE(isOK && "Actions dump does not have expected contents");
}

TEST(DriverTests, CompileToLllvmIRAsm) {
  DrvTestHarness h(A("-emit-llvm", "-S", "foo.go", nullptr));

  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
    Action compile
      inputs:
        inputfile Artifact arg(foo.go)
      output:
        Artifact file(foo.ll)
  )RAW_RESULT");

  unsigned res = h.Perform();
  ASSERT_TRUE(res == 0 && "Setup failed");

  bool isOK = h.expectActions(exp);
  EXPECT_TRUE(isOK && "Actions dump does not have expected contents");
}

TEST(DriverTests, AssembleAction) {
  DrvTestHarness h(A("-c", "foo.s", "-o", "blah.o", nullptr));

  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
    Action assemble
      inputs:
        inputfile Artifact arg(foo.s)
      output:
        Artifact arg(blah.o)
  )RAW_RESULT");

  unsigned res = h.Perform();
  ASSERT_TRUE(res == 0 && "Setup failed");

  bool isOK = h.expectActions(exp);
  EXPECT_TRUE(isOK && "Actions dump does not have expected contents");
}

TEST(DriverTests, CompileAndLinkAction) {
  DrvTestHarness h(A("foo1.go", "foo2.go", "-o", "foo.exe", nullptr));

  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
    Action compile+assemble
      inputs:
        inputfile Artifact arg(foo1.go)
        inputfile Artifact arg(foo2.go)
      output:
        Artifact file(/tmp/out.compile+assemble.0)
    Action link
      inputs:
        compile+assemble
      output:
        Artifact arg(foo.exe)
  )RAW_RESULT");

  unsigned res = h.Perform();
  ASSERT_TRUE(res == 0 && "Setup failed");

  bool isOK = h.expectActions(exp);
  EXPECT_TRUE(isOK && "Actions dump does not have expected contents");
}

TEST(DriverTests, DummyCompileCAction) {
  DrvTestHarness h(A("-c", "-x", "c", "-", "-o", "/dev/null", nullptr));

  DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
    Action readstdin
      inputs:
      output:
        Artifact file(/tmp/out.readstdin.0)
    Action compile+assemble
      inputs:
        readstdin
      output:
        Artifact arg(/dev/null)
  )RAW_RESULT");

  unsigned res = h.Perform();
  ASSERT_TRUE(res == 0 && "Setup failed");

  bool isOK = h.expectActions(exp);
  EXPECT_TRUE(isOK && "Actions dump does not have expected contents");
}


} // namespace
