#include "clang-c/CXCompilationDatabase.h"
#include "CXString.h"
#include "clang/Tooling/CompilationDatabase.h"
#include <cstdio>

using namespace clang;
using namespace clang::tooling;

extern "C" {

// FIXME: do something more useful with the error message
CXCompilationDatabase
clang_CompilationDatabase_fromDirectory(const char *BuildDir,
                                        CXCompilationDatabase_Error *ErrorCode)
{
  std::string ErrorMsg;
  CXCompilationDatabase_Error Err = CXCompilationDatabase_NoError;

  std::unique_ptr<CompilationDatabase> db =
      CompilationDatabase::loadFromDirectory(BuildDir, ErrorMsg);

  if (!db) {
    fprintf(stderr, "LIBCLANG TOOLING ERROR: %s\n", ErrorMsg.c_str());
    Err = CXCompilationDatabase_CanNotLoadDatabase;
  }

  if (ErrorCode)
    *ErrorCode = Err;

  return db.release();
}

void
clang_CompilationDatabase_dispose(CXCompilationDatabase CDb)
{
  delete static_cast<CompilationDatabase *>(CDb);
}

struct AllocatedCXCompileCommands
{
  std::vector<CompileCommand> CCmd;

  AllocatedCXCompileCommands(std::vector<CompileCommand> Cmd)
      : CCmd(std::move(Cmd)) {}
};

CXCompileCommands
clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase CDb,
                                             const char *CompleteFileName)
{
  if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
    std::vector<CompileCommand> CCmd(db->getCompileCommands(CompleteFileName));
    if (!CCmd.empty())
      return new AllocatedCXCompileCommands(std::move(CCmd));
  }

  return nullptr;
}

CXCompileCommands
clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase CDb) {
  if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
    std::vector<CompileCommand> CCmd(db->getAllCompileCommands());
    if (!CCmd.empty())
      return new AllocatedCXCompileCommands(std::move(CCmd));
  }

  return nullptr;
}

void
clang_CompileCommands_dispose(CXCompileCommands Cmds)
{
  delete static_cast<AllocatedCXCompileCommands *>(Cmds);
}

unsigned
clang_CompileCommands_getSize(CXCompileCommands Cmds)
{
  if (!Cmds)
    return 0;

  AllocatedCXCompileCommands *ACC =
    static_cast<AllocatedCXCompileCommands *>(Cmds);

  return ACC->CCmd.size();
}

CXCompileCommand
clang_CompileCommands_getCommand(CXCompileCommands Cmds, unsigned I)
{
  if (!Cmds)
    return nullptr;

  AllocatedCXCompileCommands *ACC =
    static_cast<AllocatedCXCompileCommands *>(Cmds);

  if (I >= ACC->CCmd.size())
    return nullptr;

  return &ACC->CCmd[I];
}

CXString
clang_CompileCommand_getDirectory(CXCompileCommand CCmd)
{
  if (!CCmd)
    return cxstring::createNull();

  CompileCommand *cmd = static_cast<CompileCommand *>(CCmd);
  return cxstring::createRef(cmd->Directory.c_str());
}

CXString
clang_CompileCommand_getFilename(CXCompileCommand CCmd)
{
  if (!CCmd)
    return cxstring::createNull();

  CompileCommand *cmd = static_cast<CompileCommand *>(CCmd);
  return cxstring::createRef(cmd->Filename.c_str());
}

unsigned
clang_CompileCommand_getNumArgs(CXCompileCommand CCmd)
{
  if (!CCmd)
    return 0;

  return static_cast<CompileCommand *>(CCmd)->CommandLine.size();
}

CXString
clang_CompileCommand_getArg(CXCompileCommand CCmd, unsigned Arg)
{
  if (!CCmd)
    return cxstring::createNull();

  CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);

  if (Arg >= Cmd->CommandLine.size())
    return cxstring::createNull();

  return cxstring::createRef(Cmd->CommandLine[Arg].c_str());
}

unsigned
clang_CompileCommand_getNumMappedSources(CXCompileCommand CCmd)
{
  if (!CCmd)
    return 0;

  return static_cast<CompileCommand *>(CCmd)->MappedSources.size();
}

CXString
clang_CompileCommand_getMappedSourcePath(CXCompileCommand CCmd, unsigned I)
{
  if (!CCmd)
    return cxstring::createNull();

  CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);

  if (I >= Cmd->MappedSources.size())
    return cxstring::createNull();

  return cxstring::createRef(Cmd->MappedSources[I].first.c_str());
}

CXString
clang_CompileCommand_getMappedSourceContent(CXCompileCommand CCmd, unsigned I)
{
  if (!CCmd)
    return cxstring::createNull();

  CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);

  if (I >= Cmd->MappedSources.size())
    return cxstring::createNull();

  return cxstring::createRef(Cmd->MappedSources[I].second.c_str());
}

} // end: extern "C"
