//===- llvm/tools/gollvm/unittests/BackendCore/TestUtils.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 "TestUtils.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/CFG.h"

namespace goBackendUnitTests {

std::string repr(llvm::Value *val) {
  std::string res;
  llvm::raw_string_ostream os(res);
  if (!val)
    os << "<null_value>";
  else
    val->print(os);
  return trimsp(os.str());
}

std::string repr(llvm::Type *t) {
  std::string res;
  llvm::raw_string_ostream os(res);
  if (t == NULL) {
    os << "<null_type>";
  } else {
    t->print(os);
  }
  return trimsp(os.str());
}

Btype *mkBackendStruct(Backend *be, ...)
{
  va_list ap;
  va_start(ap, be);

  std::vector<Backend::Btyped_identifier> fields;
  Btype *ct = va_arg(ap, Btype *);
  while (ct != nullptr) {
    Location loc;
    const char *fieldName = va_arg(ap, const char *);
    assert(fieldName);
    fields.push_back(Backend::Btyped_identifier(fieldName, ct, loc));
    ct = va_arg(ap, Btype *);
  }
  return be->struct_type(fields);
}

Btype *mkBackendThreeFieldStruct(Backend *be) {
  return mkBackendStruct(be,
                         be->bool_type(), "f1",
                         be->pointer_type(be->float_type(32)), "f2",
                         be->integer_type(true, 64), "f3",
                         nullptr);
}

llvm::StructType *mkLlvmStruct(llvm::LLVMContext *context, ...)
{
  va_list ap;
  va_start(ap, context);

  llvm::SmallVector<llvm::Type *, 64> smv;
  llvm::Type *typ = va_arg(ap, llvm::Type *);
  assert(typ);
  while (typ != nullptr) {
    smv.push_back(typ);
    typ = va_arg(ap, llvm::Type *);
  }
  return llvm::StructType::get(*context, smv);
}

llvm::StructType *mkLlvmThreeFieldStruct(llvm::LLVMContext &context) {
  llvm::Type *flt = llvm::Type::getFloatTy(context);
  return mkLlvmStruct(&context,
                      llvm::Type::getInt8Ty(context),
                      llvm::PointerType::get(flt, 0),
                      llvm::IntegerType::get(context, 64),
                      nullptr);
}

Btype *mkTwoFieldStruct(Backend *be, Btype *t1, Btype *t2)
{
  return mkBackendStruct(be, t1, "f1", t2, "f2", nullptr);
}

llvm::Type *mkTwoFieldLLvmStruct(llvm::LLVMContext &context,
                                 llvm::Type *t1, llvm::Type *t2)
{
  return mkLlvmStruct(&context, t1, t2, nullptr);
}

Backend::Btyped_identifier mkid(Btype *t) {
  static unsigned ctr = 1;
  char buf[128];
  sprintf(buf, "id%u", ctr++);
  return Backend::Btyped_identifier(buf, t, Location());
}

BFunctionType *mkFuncTyp(Backend *be, ...) {
  va_list ap;

  va_start(ap, be);

  Backend::Btyped_identifier receiver("rec", NULL, Location());
  std::vector<Backend::Btyped_identifier> results;
  std::vector<Backend::Btyped_identifier> params;
  Btype *result_type = NULL;

  unsigned tok = va_arg(ap, unsigned);
  while (tok != L_END) {
    switch (tok) {
    case L_RCV:
      receiver.btype = va_arg(ap, Btype *);
      break;
    case L_PARM:
      params.push_back(mkid(va_arg(ap, Btype *)));
      break;
    case L_RES:
      results.push_back(mkid(va_arg(ap, Btype *)));
      break;
    case L_RES_ST:
      result_type = va_arg(ap, Btype *);
      break;
    default: {
      assert(false && "internal error");
      return NULL;
    }
    }
    tok = va_arg(ap, unsigned);
  }

  if (results.size() > 1)
    result_type = be->struct_type(results);

  Btype *ft = be->function_type(receiver, params, results,
                                result_type, Location());
  return ft->castToBFunctionType();
}

llvm::Type *mkLLFuncTyp(llvm::LLVMContext *context, ...) {
  va_list ap;

  llvm::SmallVector<llvm::Type *, 4> params(0);
  llvm::SmallVector<llvm::Type *, 4> results(0);
  llvm::Type *recv_typ = NULL;
  llvm::Type *res_styp = NULL;

  va_start(ap, context);
  unsigned tok = va_arg(ap, unsigned);
  while (tok != L_END) {
    switch (tok) {
    case L_RCV:
      recv_typ = va_arg(ap, llvm::Type *);
      break;
    case L_PARM:
      params.push_back(va_arg(ap, llvm::Type *));
      break;
    case L_RES:
      results.push_back(va_arg(ap, llvm::Type *));
      break;
    case L_RES_ST:
      res_styp = va_arg(ap, llvm::Type *);
      break;
    default: {
      assert(false && "internal error");
      return NULL;
    }
    }
    tok = va_arg(ap, unsigned);
  }

  llvm::SmallVector<llvm::Type *, 4> elems(0);
  llvm::Type *llit = llvm::IntegerType::get(*context, 8);
  elems.push_back(llvm::PointerType::get(llit, 0));
  if (recv_typ)
    elems.push_back(recv_typ);
  for (auto pt : params)
    elems.push_back(pt);

  llvm::Type *rtyp = NULL;
  if (results.empty())
    rtyp = llvm::Type::getVoidTy(*context);
  else if (results.size() == 1)
    rtyp = results[0];
  else {
    rtyp = res_styp;
  }
  return llvm::FunctionType::get(rtyp, elems, false);
}

bool llvmTypesEquiv(llvm::Type *t1, llvm::Type *t2)
{
  if (t1->getTypeID() != t2->getTypeID())
    return false;
  if (t1->getNumContainedTypes() != t2->getNumContainedTypes())
    return false;
  for (unsigned idx = 0; idx < t1->getNumContainedTypes(); ++idx)
    if (!llvmTypesEquiv(t1->getContainedType(idx),
                        t2->getContainedType(idx)))
      return false;
  return true;
}

Bfunction *mkFunci32o64(Backend *be, const char *fname, bool mkParams) {
  Btype *bi64t = be->integer_type(false, 64);
  Btype *bi32t = be->integer_type(false, 32);
  Btype *bpi64t = be->pointer_type(bi64t);
  Btype *befty =
      mkFuncTyp(be,
                L_PARM, bi32t, L_PARM, bi32t, L_PARM, bpi64t,
                L_RES, bi64t, L_END);
  bool visible = true;
  bool is_declaration = false;
  bool is_inl = true;
  bool split_stack = true;
  bool unique_sec = false;
  bool no_ret = false;
  Location loc;
  Bfunction *func = be->function(befty, fname, fname, visible,
                                 is_declaration, is_inl,
                                 split_stack, no_ret, unique_sec, loc);
  if (mkParams) {
    be->parameter_variable(func, "param1", bi32t, false, loc);
    be->parameter_variable(func, "param2", bi32t, false, loc);
    be->parameter_variable(func, "param3", bpi64t, false, loc);
  }
  return func;
}

Bfunction *mkFuncFromType(Backend *be, const char *fname,
                          BFunctionType *befty, Location loc)
{
  bool visible = true;
  bool is_declaration = false;
  bool is_inl = true;
  bool split_stack = true;
  bool unique_sec = false;
  bool no_ret = false;
  Bfunction *func = be->function(befty, fname, fname, visible,
                                 is_declaration, is_inl,
                                 split_stack, no_ret, unique_sec, loc);
  const std::vector<Btype *> &paramTypes = befty->paramTypes();
  for (unsigned idx = 0; idx < paramTypes.size(); ++idx) {
    std::stringstream ss;
    ss << "p" << idx;
    be->parameter_variable(func, ss.str(), paramTypes[idx], false, loc);
  }
  return func;
}

Bexpression *mkUIntConst(Backend *be, uint64_t val, unsigned bits) {
  mpz_t mpz_val;
  memset(&mpz_val, '0', sizeof(mpz_val));
  mpz_init_set_ui(mpz_val, val);
  Btype *but = be->integer_type(true, bits);
  Bexpression *rval = be->integer_constant_expression(but, mpz_val);
  mpz_clear(mpz_val);
  return rval;
}

Bexpression *mkIntConst(Backend *be, int64_t val, unsigned bits) {
  mpz_t mpz_val;
  memset(&mpz_val, '0', sizeof(mpz_val));
  mpz_init_set_si(mpz_val, val);
  Btype *bit = be->integer_type(false, bits);
  Bexpression *rval = be->integer_constant_expression(bit, mpz_val);
  mpz_clear(mpz_val);
  return rval;
}

Bexpression *mkInt64Const(Backend *be, int64_t val) {
  return mkIntConst(be, val, 64);
}

Bexpression *mkUint64Const(Backend *be, uint64_t val) {
  return mkUIntConst(be, val, 64);
}

Bexpression *mkInt32Const(Backend *be, int32_t val) {
  return mkIntConst(be, val, 32);
}

Bexpression *mkFloat64Const(Backend *be, double val) {
  mpfr_t mpfr_val;

  mpfr_init(mpfr_val);
  mpfr_set_d(mpfr_val, val, GMP_RNDN);
  Btype *bf64t = be->float_type(64);
  Bexpression *beval = be->float_constant_expression(bf64t, mpfr_val);
  mpfr_clear(mpfr_val);
  return beval;
}

// Return func desc type
Btype *mkFuncDescType(Backend *be)
{
  assert(be);
  Btype *bt = be->bool_type();
  Btype *pbt = be->pointer_type(bt);
  Btype *uintptrt = be->integer_type(true, be->type_size(pbt)*8);
  Btype *fdescst = mkBackendStruct(be, uintptrt, "f1", nullptr);
  return fdescst;
}

Bexpression *mkFuncDescExpr(Backend *be, Bfunction *fcn)
{
  assert(be);
  assert(fcn);
  Location loc;
  Btype *bt = be->bool_type();
  Btype *pbt = be->pointer_type(bt);
  Btype *uintptrt = be->integer_type(true, be->type_size(pbt)*8);
  Btype *fdescst = mkFuncDescType(be);
  Bexpression *fp = be->function_code_expression(fcn, loc);
  Bexpression *fpuint = be->convert_expression(uintptrt, fp, loc);
  std::vector<Bexpression *> vals;
  vals.push_back(fpuint);
  return be->constructor_expression(fdescst, vals, loc);
}

Bblock *mkBlockFromStmt(Backend *be, Bfunction *func, Bstatement *st) {
  const std::vector<Bvariable *> empty;
  Bblock *b = be->block(func, nullptr, empty, Location(), Location());
  std::vector<Bstatement *> stlist;
  stlist.push_back(st);
  be->block_add_statements(b, stlist);
  return b;
}

Bstatement *addStmtToBlock(Backend *be, Bblock *block, Bstatement *st) {
  std::vector<Bstatement *> stlist;
  stlist.push_back(st);
  be->block_add_statements(block, stlist);
  return st;
}

Bstatement *addExprToBlock(Backend *be, Bfunction *func,
                           Bblock *block, Bexpression *e) {
  Bstatement *es = be->expression_statement(func, e);
  std::vector<Bstatement *> stlist;
  stlist.push_back(es);
  be->block_add_statements(block, stlist);
  return es;
}

class NodeReprVisitor {
 public:
  NodeReprVisitor() : os_(str_) { }

  std::string result() { return os_.str(); }

  void visitNodePre(Bnode *node) { }

  void visitNodePost(Bnode *node) {
    assert(node);
    Bexpression *expr = node->castToBexpression();
    if (expr) {
      for (auto inst : expr->instructions()) {
        inst->print(os_);
        os_ << "\n";
      }
    }
    assert(node->flavor() != N_IfStmt &&
           node->flavor() != N_GotoStmt &&
           node->flavor() != N_LabelStmt &&
           node->flavor() != N_SwitchStmt);
  }

 private:
  std::string str_;
  llvm::raw_string_ostream os_;
};

std::string repr(Bnode *node) {
  if (!node)
    return "<null Bnode ptr>";

  NodeReprVisitor vis;
  simple_walk_nodes(node, vis);
  return trimsp(vis.result());
}

FcnTestHarness::FcnTestHarness(const char *fcnName)
    : context_()
    , be_(new Llvm_backend(context_, nullptr, nullptr))
    , func_(nullptr)
    , entryBlock_(nullptr)
    , curBlock_(nullptr)
    , nextLabel_(nullptr)
    , lineNum_(1)
    , finished_(false)
    , returnAdded_(false)
    , emitDumpFilesOnDiff_(false)
    , findOrphanBBs_(true)
{
  // establish initial file so as to make verifier happy
  be_->linemap()->start_file("unit_testing.go", 1);
  loc_ = be_->linemap()->get_location(lineNum_);

  // Eager function creation if name not specified
  if (fcnName) {
    func_ = mkFunci32o64(be(), fcnName);
    entryBlock_ = be()->block(func_, nullptr, emptyVarList_, loc_, loc_);
    curBlock_ = be()->block(func_, nullptr, emptyVarList_, loc_, loc_);
  }

  // debugging
  if (getenv("GOLLVM_UNITTESTS_BACKENDCORE_EMITDUMPFILES"))
    emitDumpFilesOnDiff_ = true;
}

FcnTestHarness::~FcnTestHarness()
{
  assert(finished_);
}

Location FcnTestHarness::newloc()
{
  loc_ = be_->linemap()->get_location(++lineNum_);
  return loc_;
}

Location FcnTestHarness::newFileLineLoc(const char *file, unsigned line)
{
  lineNum_ = line;
  be_->linemap()->start_file(file, lineNum_);
  loc_ = be_->linemap()->get_location(lineNum_);
  return loc_;
}

Bfunction *FcnTestHarness::mkFunction(const char *fcnName, BFunctionType *befty)
{
  func_ = mkFuncFromType(be(), fcnName, befty, loc_);
  entryBlock_ = be()->block(func_, nullptr, emptyVarList_, loc_, loc_);
  curBlock_ = be()->block(func_, nullptr, emptyVarList_, loc_, loc_);
  return func_;
}

Bvariable *FcnTestHarness::mkLocal(const char *name,
                                   Btype *typ,
                                   Bexpression *init)
{
  assert(func_);
  Bvariable *v = be()->local_variable(func_, name, typ, nullptr, true, loc_);
  if (!init)
    init = be()->zero_expression(typ);
  Bstatement *is = be()->init_statement(func_, v, init);
  addStmtToBlock(be(), curBlock_, is);
  return v;
}

void FcnTestHarness::mkAssign(Bexpression *lhs,
                              Bexpression *rhs,
                              AppendDisp disp)
{
  assert(func_);
  Bstatement *as = be()->assignment_statement(func_, lhs, rhs, loc_);
  if (disp == YesAppend)
    addStmtToBlock(be(), curBlock_, as);
}

Bstatement *FcnTestHarness::mkExprStmt(Bexpression *expr, AppendDisp disp)
{
  assert(func_);
  Bstatement *es = be()->expression_statement(func_, expr);
  if (disp == YesAppend)
    addStmtToBlock(be(), curBlock_, es);
  return es;
}

Bexpression *FcnTestHarness::mkCallExpr(Backend *be, Bfunction *fun, ...)
{
  va_list ap;

  va_start(ap, fun);
  Bexpression *fn = be->function_code_expression(fun, loc_);
  std::vector<Bexpression *> args;
  Bexpression *e = va_arg(ap, Bexpression *);
  while (e) {
    args.push_back(e);
    e = va_arg(ap, Bexpression *);
  }
  Bexpression *call = be->call_expression(func_, fn, args, nullptr, loc_);
  return call;
}

Bstatement *FcnTestHarness::mkReturn(Bexpression *expr, AppendDisp disp)
{
  std::vector<Bexpression *> vals;
  vals.push_back(expr);
  return mkReturn(vals, disp);
}

Bstatement *FcnTestHarness::mkReturn(const std::vector<Bexpression *> &vals,
                                     AppendDisp disp)
{
  assert(func_);
  Bstatement *ret = be()->return_statement(func_, vals, loc_);
  if (disp == YesAppend) {
    addStmtToBlock(be(), curBlock_, ret);
    returnAdded_ = true;
  }
  return ret;
}

Bstatement *FcnTestHarness::mkIf(Bexpression *cond,
                                 Bstatement *trueStmt,
                                 Bstatement *falseStmt,
                                 AppendDisp disp)
{
  assert(func_);
  Bblock *trueBlock = mkBlockFromStmt(be(), func_, trueStmt);
  Bblock *falseBlock = nullptr;
  if (falseStmt)
    falseBlock = mkBlockFromStmt(be(), func_, falseStmt);
  Bstatement *ifst = be()->if_statement(func_, cond,
                                        trueBlock, falseBlock, loc_);
  if (disp == YesAppend)
    addStmtToBlock(be(), curBlock_, ifst);
  return ifst;
}

Bstatement *FcnTestHarness::mkSwitch(Bexpression *swval,
                       const std::vector<std::vector<Bexpression*> >& cases,
                       const std::vector<Bstatement*>& statements,
                                     AppendDisp disp)
{
  assert(func_);
  Bstatement *swst = be()->switch_statement(func_, swval,
                                            cases, statements, loc_);
  if (disp == YesAppend)
    addStmtToBlock(be(), curBlock_, swst);
  return swst;
}


void FcnTestHarness::addStmt(Bstatement *stmt)
{
  assert(func_);
  addStmtToBlock(be(), curBlock_, stmt);
}

void FcnTestHarness::newBlock(std::vector<Bvariable *> *varlist)
{
  assert(func_);

  if (!varlist)
    varlist = &emptyVarList_;

  // Create label for new block and append jump to current block
  std::string lab = be()->namegen("_lab");
  Blabel *blab = be()->label(func_, lab, loc_);
  Bstatement *gots = be()->goto_statement(blab, loc_);
  addStmtToBlock(be(), curBlock_, gots);

  // Turn current block into statement and tack onto entry block. Weird,
  // but this is the pardigm for gofrontend.
  Bstatement *bst = be()->block_statement(curBlock_);
  if (nextLabel_) {
    Bstatement *ldef = be()->label_definition_statement(nextLabel_);
    bst = be()->compound_statement(ldef, bst);
  }
  addStmtToBlock(be(), entryBlock_, bst);
  nextLabel_ = blab;
  returnAdded_ = false;

  // New block
  curBlock_ = be()->block(func_, nullptr, *varlist, loc_, loc_);
}

bool FcnTestHarness::expectStmt(Bstatement *st, const std::string &expected)
{
 std::string reason;
 std::string actual(repr(st));
  bool equal = difftokens(expected, actual, reason);
  if (! equal)
    complainOnNequal(reason, expected, actual, emitDumpFilesOnDiff_);
  return equal;
}

bool FcnTestHarness::expectValue(llvm::Value *val, const std::string &expected)
{
  std::string reason;
  std::string actual(repr(val));
  bool equal = difftokens(expected, actual, reason);
  if (! equal)
    complainOnNequal(reason, expected, actual, emitDumpFilesOnDiff_);
  return equal;
}

bool FcnTestHarness::expectBlock(const std::string &expected)
{
  std::string reason;
  std::string actual(repr(curBlock_));
  bool equal = difftokens(expected, actual, reason);
  if (! equal)
    complainOnNequal(reason, expected, actual, emitDumpFilesOnDiff_);
  return equal;
}

bool FcnTestHarness::expectModuleDumpContains(const std::string &expected)
{
  std::string res;
  llvm::raw_string_ostream os(res);
  be()->module().print(os, nullptr);
  std::string actual(trimsp(os.str()));
  return containstokens(actual, expected);
}

unsigned FcnTestHarness::countInstancesInModuleDump(const std::string &expected)
{
  std::string res;
  llvm::raw_string_ostream os(res);
  be()->module().print(os, nullptr);
  std::string actual(trimsp(os.str()));
  return countinstances(actual, expected);
}

bool FcnTestHarness::expectRepr(Bnode *node, const std::string &expected)
{
  std::string reason;
  std::string actual(repr(node));
  bool equal = difftokens(expected, actual, reason);
  if (! equal)
    complainOnNequal(reason, expected, actual, emitDumpFilesOnDiff_);
  return equal;
}

bool FcnTestHarness::finish(DebugDisposition whatToDoWithDebugInfo)
{
  if (func_) {

    // Emit a label def for the pending block if needed
    Bstatement *bst = be()->block_statement(curBlock_);
    if (nextLabel_) {
      Bstatement *ldef = be()->label_definition_statement(nextLabel_);
      bst = be()->compound_statement(ldef, bst);
    }

    // Add current block as stmt to entry block
    addStmtToBlock(be(), entryBlock_, bst);

    // Set function body
    be()->function_set_body(func_, entryBlock_);

  }
    // Finalize export data. This has the side effect of finalizing
    // debug meta-data, which we need to do before invoking the verifier.
  be()->finalizeExportData();

  // Strip debug info now if requested
  if (whatToDoWithDebugInfo == StripDebugInfo)
    llvm::StripDebugInfo(be()->module());

  // Look for non-entry blocks with no CFG preds, since they
  // are nearly always an indication that something is wrong.
  bool brokenBlock = false;
  if (func_ && findOrphanBBs_) {
    for (llvm::BasicBlock &bb : *func_->function()) {
      if (&bb == &func_->function()->getEntryBlock())
        continue;
      if (! bb.getParent()) {
        std::cerr << "** block with no parent:\n";
        llvm::Value *blockVal = &bb;
        std::cerr << repr(blockVal);
        brokenBlock = true;
      }
      if (llvm::pred_begin(&bb) == llvm::pred_end(&bb)) {
        std::cerr << "** block has no predecessors:\n";
        llvm::Value *blockVal = &bb;
        std::cerr << repr(blockVal);
        brokenBlock = true;
      }
    }
  }

  // Verify module
  bool broken = llvm::verifyModule(be()->module(), &llvm::dbgs());

  // Mark finished
  finished_ = true;
  curBlock_ = entryBlock_;

  return broken || brokenBlock;
}

} // end namespace goBackEndUnitTests
