#include <cassert>
#include <list>
#include <string>

#include "llvm/Linker.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"

#include "llvm/ADT/OwningPtr.h"

#include "llvm/Bitcode/ReaderWriter.h"

#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/PassManagerBuilder.h"
#include "llvm/Support/system_error.h"

#include "llvm/Target/TargetData.h"

static llvm::cl::list<std::string>
InputFilenames(llvm::cl::Positional, llvm::cl::OneOrMore,
               llvm::cl::desc("<input bitcode files>"));

static llvm::cl::list<std::string>
OutputFilenames("o", llvm::cl::desc("Override output filename"),
                llvm::cl::value_desc("output bitcode file"));


static llvm::Module* getModuleFromFilename(std::string& Filename,
                                           llvm::LLVMContext& Ctx,
                                           std::string& ErrMsg) {
  llvm::OwningPtr<llvm::MemoryBuffer> MB;
  llvm::MemoryBuffer::getFile(Filename, MB);
  llvm::Module* M = llvm::ParseBitcodeFile(MB.get(), Ctx, &ErrMsg);
  assert(M && ErrMsg);
  return M;
}

static void optimizeModule(llvm::Module* M) {
  llvm::PassManager Passes;

  const std::string &ModuleDataLayout = M->getDataLayout();
  if (!ModuleDataLayout.empty())
    if (llvm::TargetData *TD = new llvm::TargetData(ModuleDataLayout))
      Passes.add(TD);

  Passes.add(llvm::createInternalizePass(true/* AllButMain*/));
#if 0
  FIXME REMOVE
  createStandardLTOPasses(&Passes,
                          /* Internalize = */false,
                          /* RunInliner = */true,
                          /* VerifyEach = */false);
#endif
  llvm::PassManagerBuilder PMBuilder;
  PMBuilder.populateLTOPassManager(Passes, false, true);
  Passes.run(*M);
}

static llvm::Module* linkFilesToModule(llvm::cl::list<std::string>& Inputs,
                                       llvm::LLVMContext& Ctx) {
  std::string ErrMsg;
  llvm::Module* M = getModuleFromFilename(Inputs[0], Ctx, ErrMsg);
  llvm::Linker Linker("llvm-ndk-link", M);

  for (unsigned i=1; i<Inputs.size(); ++i) {
    llvm::Module* M = getModuleFromFilename(Inputs[i], Ctx, ErrMsg);
    if (!Linker.LinkInModule(M, &ErrMsg)) {
      assert(false && ErrMsg);
    }
    optimizeModule(M);
  }
  M = Linker.releaseModule();

  llvm::PassManager PM;
  const std::string &ModuleDataLayout = M->getDataLayout();
  if (!ModuleDataLayout.empty())
    if (llvm::TargetData *TD = new llvm::TargetData(ModuleDataLayout))
      PM.add(TD);

#if 0
  FIXME REMOVE
  llvm::createStandardFunctionPasses(&PM, 3 /* OptLevel*/);
  llvm::createStandardModulePasses(&PM,
                                   3, /* OptimizationLevel */
                                   true, /* OptimizeSize */
                                   true, /* UnitAtATime */
                                   true, /* UnrollLoops */
                                   true, /* SimplifyLibCalls */
                                   false, /* HaveExceptions */
                                   NULL /* InliningPass */);
#endif

  llvm::PassManagerBuilder PMBuilder;
  //PMBuilder.OptLevel = 3;
  //PMBuilder.populateFunctionPassManager(PM);

  PMBuilder.OptLevel = 3;
  PMBuilder.SizeLevel = true;
  PMBuilder.DisableUnitAtATime = false;
  PMBuilder.DisableUnrollLoops = false;
  PMBuilder.DisableSimplifyLibCalls = false;
  PMBuilder.populateModulePassManager(PM);

  PM.run(*M);
  return M;
}

int main(int argc, char** argv) {
  llvm::llvm_shutdown_obj _ShutdownObj;
  llvm::cl::ParseCommandLineOptions(argc, argv, "P-NDK Link Tool");

  llvm::LLVMContext& Ctx = llvm::getGlobalContext();
  std::string ErrMsg;
  llvm::raw_fd_ostream FOS(OutputFilenames[0].c_str(), ErrMsg);
  assert(!FOS.has_error());

  // No need to link (just one file).
  // Output Directly.
  if (InputFilenames.size() == 1) {
    llvm::OwningPtr<llvm::Module> M(getModuleFromFilename(InputFilenames[0],
                                                           Ctx,
                                                           ErrMsg));
    llvm::WriteBitcodeToFile(M.get(), FOS);
    return 0;
  }

  llvm::OwningPtr<llvm::Module> M(linkFilesToModule(InputFilenames, Ctx));
  llvm::WriteBitcodeToFile(M.get(), FOS);
  assert(!FOS.has_error());
  return 0;
}
