//===- BuildSystem.cpp - Utilities for use by build systems ---------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements various utilities for use by build systems.
//
//===----------------------------------------------------------------------===//

#include "clang-c/BuildSystem.h"
#include "CXString.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"

using namespace clang;
using namespace llvm::sys;

unsigned long long clang_getBuildSessionTimestamp(void) {
  return llvm::sys::toTimeT(std::chrono::system_clock::now());
}

DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::vfs::YAMLVFSWriter,
                                   CXVirtualFileOverlay)

CXVirtualFileOverlay clang_VirtualFileOverlay_create(unsigned) {
  return wrap(new llvm::vfs::YAMLVFSWriter());
}

enum CXErrorCode
clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay VFO,
                                        const char *virtualPath,
                                        const char *realPath) {
  if (!VFO || !virtualPath || !realPath)
    return CXError_InvalidArguments;
  if (!path::is_absolute(virtualPath))
    return CXError_InvalidArguments;
  if (!path::is_absolute(realPath))
    return CXError_InvalidArguments;

  for (path::const_iterator
         PI = path::begin(virtualPath),
         PE = path::end(virtualPath); PI != PE; ++PI) {
    StringRef Comp = *PI;
    if (Comp == "." || Comp == "..")
      return CXError_InvalidArguments;
  }

  unwrap(VFO)->addFileMapping(virtualPath, realPath);
  return CXError_Success;
}

enum CXErrorCode
clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay VFO,
                                            int caseSensitive) {
  if (!VFO)
    return CXError_InvalidArguments;
  unwrap(VFO)->setCaseSensitivity(caseSensitive);
  return CXError_Success;
}

enum CXErrorCode
clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned,
                                       char **out_buffer_ptr,
                                       unsigned *out_buffer_size) {
  if (!VFO || !out_buffer_ptr || !out_buffer_size)
    return CXError_InvalidArguments;

  llvm::SmallString<256> Buf;
  llvm::raw_svector_ostream OS(Buf);
  unwrap(VFO)->write(OS);

  StringRef Data = OS.str();
  *out_buffer_ptr = static_cast<char*>(llvm::safe_malloc(Data.size()));
  *out_buffer_size = Data.size();
  memcpy(*out_buffer_ptr, Data.data(), Data.size());
  return CXError_Success;
}

void clang_free(void *buffer) {
  free(buffer);
}

void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay VFO) {
  delete unwrap(VFO);
}


struct CXModuleMapDescriptorImpl {
  std::string ModuleName;
  std::string UmbrellaHeader;
};

CXModuleMapDescriptor clang_ModuleMapDescriptor_create(unsigned) {
  return new CXModuleMapDescriptorImpl();
}

enum CXErrorCode
clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor MMD,
                                                 const char *name) {
  if (!MMD || !name)
    return CXError_InvalidArguments;

  MMD->ModuleName = name;
  return CXError_Success;
}

enum CXErrorCode
clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor MMD,
                                            const char *name) {
  if (!MMD || !name)
    return CXError_InvalidArguments;

  MMD->UmbrellaHeader = name;
  return CXError_Success;
}

enum CXErrorCode
clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor MMD, unsigned,
                                       char **out_buffer_ptr,
                                       unsigned *out_buffer_size) {
  if (!MMD || !out_buffer_ptr || !out_buffer_size)
    return CXError_InvalidArguments;

  llvm::SmallString<256> Buf;
  llvm::raw_svector_ostream OS(Buf);
  OS << "framework module " << MMD->ModuleName << " {\n";
  OS << "  umbrella header \"";
  OS.write_escaped(MMD->UmbrellaHeader) << "\"\n";
  OS << '\n';
  OS << "  export *\n";
  OS << "  module * { export * }\n";
  OS << "}\n";

  StringRef Data = OS.str();
  *out_buffer_ptr = static_cast<char*>(llvm::safe_malloc(Data.size()));
  *out_buffer_size = Data.size();
  memcpy(*out_buffer_ptr, Data.data(), Data.size());
  return CXError_Success;
}

void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor MMD) {
  delete MMD;
}
