//===- llvm/tools/gollvm/unittests/TestUtils/DiffUtils.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 "DiffUtils.h"

#include <assert.h>
#include <iostream>
#include <sstream>

namespace goBackendUnitTests {

DECLARE_EXPECTED_OUTPUT(baseline, R"RAW_RESULT(
    abc
    def
    xyz
)RAW_RESULT");

// macroLineAtStart returns TRUE if the line number reported by the
// compiler for __LINE__ in a macro instantiation points to the start
// of the DECLARE_EXPECTED_OUTPUT macro use, as opposed to the end.
//
// Fun fact: there is some disagreement among C++ compilers about what
// the line is. Some compilers decided that __LINE__ for the macro
// above is the starting line (16) and some decide that it's the
// ending line (20). Which one will matter for the machinery that does
// test remastering.
static bool macroLineAtStart() {
  if (baseline.line == 16) {
    return true;
  } else if (baseline.line == 20) {
    return false;
  } else {
    assert(false && "macroLineAtStart broken -- source edited?");
  }
}

std::string trimsp(const std::string &s) {
  size_t firstsp = s.find_first_not_of(" \n");
  if (firstsp == std::string::npos)
    return s;
  size_t lastsp = s.find_last_not_of(" \n");
  return s.substr(firstsp, (lastsp - firstsp + 1));
}

std::vector<std::string> tokenize(const std::string &s) {
  std::vector<std::string> tokens;

  const std::string del(" \t\n");
  size_t np = s.find_first_not_of(del, 0);
  size_t pos = s.find_first_of(del, np);
  while (pos != std::string::npos || np != std::string::npos) {
    tokens.push_back(s.substr(np, pos - np));
    np = s.find_first_not_of(del, pos);
    pos = s.find_first_of(del, np);
  }
  return tokens;
}

std::string vectostr(const std::vector<std::string> &tv) {
  std::stringstream ss;
  unsigned wc = 0;
  for (auto s : tv)
    ss << " " << wc++ << "[" << s << "]";
  return ss.str();
}

bool difftokens(const std::string &expected, const std::string &result,
                std::string &diffreason)
{
  std::vector<std::string> expv = tokenize(expected);
  std::vector<std::string> resv = tokenize(result);
  unsigned mins = std::min(expv.size(), resv.size());
  unsigned maxs = std::max(expv.size(), resv.size());
  std::stringstream ss;
  bool rval = true;
  if (expv.size() != resv.size()) {
    ss << "lengths differ (" << expv.size() << " vs " << resv.size()
       << ") extra " << (expv.size() > resv.size() ? "result" : "expected")
       << " tokens: ";
    for (unsigned idx = 0; idx < maxs; ++idx) {
      if (idx >= mins)
        ss << (idx < expv.size() ? expv[idx] : resv[idx]) << " ";
    }
    ss << "\n";
    rval = false;
  }
  for (unsigned idx = 0; idx < mins; ++idx) {
    if (expv[idx] != resv[idx]) {
      ss << "token vector diff at slot " << idx << " (expected '" << expv[idx]
         << "' result '" << resv[idx] << "')";
      rval = false;
      break;
    }
  }
  if (! rval)
    diffreason = ss.str();
  return rval;
}

bool containstokens(const std::string &text, const std::string &pat)
{
  std::vector<std::string> textToks = tokenize(text);
  std::vector<std::string> patToks = tokenize(pat);
  for (unsigned ti = 0; ti < textToks.size(); ++ti) {
    bool failed = false;
    for (unsigned tic = ti, pi = 0; pi < patToks.size(); ++pi, ++tic) {
      if (tic >= textToks.size() || patToks[pi] != textToks[tic]) {
        failed = true;
        break;
      }
    }
    if (failed)
      continue;
    return true;
  }
  return false;
}

unsigned countinstances(const std::string &text, const std::string &pat)
{
  unsigned instances = 0;
  std::vector<std::string> textToks = tokenize(text);
  std::vector<std::string> patToks = tokenize(pat);
  for (unsigned ti = 0; ti < textToks.size(); ++ti) {
    bool fail = false;
    for (unsigned tic = ti, pi = 0; pi < patToks.size(); ++pi, ++tic) {
      if (tic >= textToks.size() || patToks[pi] != textToks[tic]) {
        fail = true;
        break;
      }
    }
    if (!fail)
      instances += 1;
  }
  return instances;
}

std::string dumpfilename(const char *tag, unsigned version) {
  std::stringstream ss;
  ss << "/tmp/" << tag << ".dump." << version << ".txt";
  return ss.str();
}

void emitStringToDumpFile(const char *tag,
                          unsigned version,
                          const std::string &payload)
{
  auto fn = dumpfilename(tag, version);
  FILE *fp = fopen(fn.c_str(), "w");
  if (fp) {
    fprintf(fp, "%s\n", payload.c_str());
    fclose(fp);
    std::cerr << "emitted dump file " << fn << "\n";
  }
}

void complainOnNequal(const std::string &reason,
                      const ExpectedDump &ed,
                      const std::string &actual)
{
  bool emitDumpFilesOnDiff = false;
  bool emitRemasterScript = false;

  if (getenv("GOLLVM_UNITTESTS_BACKENDCORE_EMITDUMPFILES") != nullptr)
    emitDumpFilesOnDiff = true;
  if (getenv("GOLLVM_UNITTESTS_EMIT_REMASTER_SCRIPT") != nullptr) {
    emitRemasterScript = true;
    emitDumpFilesOnDiff = true;
  }

  std::cerr << reason << "\n";
  const std::string &expected = ed.content;
  std::cerr << "expected dump:\n" << expected << "\n";
  std::cerr << "actual dump:\n" << actual << "\n";
  unsigned mls = macroLineAtStart() ? 1 : 0;
  if (emitDumpFilesOnDiff) {
    static unsigned filecount;
    static FILE *outfp; // script
    emitStringToDumpFile("expected", filecount, expected);
    emitStringToDumpFile("actual", filecount, actual);
    if (emitRemasterScript) {
      // HACK: no explicit close for this file. Assume that it will
      // be closed when the unit test finishes running.
      if (outfp == nullptr) {
        outfp = fopen("/tmp/remaster-inputs.txt", "w");
        fprintf(stderr, "... emitting remaster inputs to file '/tmp/remaster-inputs.txt'\n");
      }
      fprintf(outfp, "%d %s %d %s %s\n", mls, ed.file, ed.line,
              dumpfilename("expected", filecount).c_str(),
              dumpfilename("actual", filecount).c_str());
      fflush(outfp);
    }
    filecount++;
  }
}

} // end namespace
