//===-- SBFileSpec.cpp ------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/API/SBFileSpec.h"
#include "SBReproducerPrivate.h"
#include "Utils.h"
#include "lldb/API/SBStream.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/PosixApi.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Stream.h"

#include "llvm/ADT/SmallString.h"

#include <inttypes.h>
#include <limits.h>

using namespace lldb;
using namespace lldb_private;

SBFileSpec::SBFileSpec() : m_opaque_up(new lldb_private::FileSpec()) {
  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBFileSpec);
}

SBFileSpec::SBFileSpec(const SBFileSpec &rhs) : m_opaque_up() {
  LLDB_RECORD_CONSTRUCTOR(SBFileSpec, (const lldb::SBFileSpec &), rhs);

  m_opaque_up = clone(rhs.m_opaque_up);
}

SBFileSpec::SBFileSpec(const lldb_private::FileSpec &fspec)
    : m_opaque_up(new lldb_private::FileSpec(fspec)) {}

// Deprecated!!!
SBFileSpec::SBFileSpec(const char *path) : m_opaque_up(new FileSpec(path)) {
  LLDB_RECORD_CONSTRUCTOR(SBFileSpec, (const char *), path);

  FileSystem::Instance().Resolve(*m_opaque_up);
}

SBFileSpec::SBFileSpec(const char *path, bool resolve)
    : m_opaque_up(new FileSpec(path)) {
  LLDB_RECORD_CONSTRUCTOR(SBFileSpec, (const char *, bool), path, resolve);

  if (resolve)
    FileSystem::Instance().Resolve(*m_opaque_up);
}

SBFileSpec::~SBFileSpec() {}

const SBFileSpec &SBFileSpec::operator=(const SBFileSpec &rhs) {
  LLDB_RECORD_METHOD(const lldb::SBFileSpec &,
                     SBFileSpec, operator=,(const lldb::SBFileSpec &), rhs);

  if (this != &rhs)
    m_opaque_up = clone(rhs.m_opaque_up);
  return LLDB_RECORD_RESULT(*this);
}

bool SBFileSpec::operator==(const SBFileSpec &rhs) const {
  LLDB_RECORD_METHOD_CONST(bool, SBFileSpec, operator==,(const SBFileSpec &rhs),
                           rhs);

  return ref() == rhs.ref();
}

bool SBFileSpec::operator!=(const SBFileSpec &rhs) const {
  LLDB_RECORD_METHOD_CONST(bool, SBFileSpec, operator!=,(const SBFileSpec &rhs),
                           rhs);

  return !(*this == rhs);
}

bool SBFileSpec::IsValid() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFileSpec, IsValid);
  return this->operator bool();
}
SBFileSpec::operator bool() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFileSpec, operator bool);

  return m_opaque_up->operator bool();
}

bool SBFileSpec::Exists() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFileSpec, Exists);

  return FileSystem::Instance().Exists(*m_opaque_up);
}

bool SBFileSpec::ResolveExecutableLocation() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBFileSpec, ResolveExecutableLocation);

  return FileSystem::Instance().ResolveExecutableLocation(*m_opaque_up);
}

int SBFileSpec::ResolvePath(const char *src_path, char *dst_path,
                            size_t dst_len) {
  LLDB_RECORD_STATIC_METHOD(int, SBFileSpec, ResolvePath,
                            (const char *, char *, size_t), src_path, dst_path,
                            dst_len);

  llvm::SmallString<64> result(src_path);
  FileSystem::Instance().Resolve(result);
  ::snprintf(dst_path, dst_len, "%s", result.c_str());
  return std::min(dst_len - 1, result.size());
}

const char *SBFileSpec::GetFilename() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFileSpec, GetFilename);

  return m_opaque_up->GetFilename().AsCString();
}

const char *SBFileSpec::GetDirectory() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFileSpec, GetDirectory);

  FileSpec directory{*m_opaque_up};
  directory.GetFilename().Clear();
  return directory.GetCString();
}

void SBFileSpec::SetFilename(const char *filename) {
  LLDB_RECORD_METHOD(void, SBFileSpec, SetFilename, (const char *), filename);

  if (filename && filename[0])
    m_opaque_up->GetFilename().SetCString(filename);
  else
    m_opaque_up->GetFilename().Clear();
}

void SBFileSpec::SetDirectory(const char *directory) {
  LLDB_RECORD_METHOD(void, SBFileSpec, SetDirectory, (const char *), directory);

  if (directory && directory[0])
    m_opaque_up->GetDirectory().SetCString(directory);
  else
    m_opaque_up->GetDirectory().Clear();
}

uint32_t SBFileSpec::GetPath(char *dst_path, size_t dst_len) const {
  LLDB_RECORD_DUMMY(uint32_t, SBFileSpec, GetPath, (char *, size_t),
                           dst_path, dst_len);

  uint32_t result = m_opaque_up->GetPath(dst_path, dst_len);

  if (result == 0 && dst_path && dst_len > 0)
    *dst_path = '\0';
  return result;
}

const lldb_private::FileSpec *SBFileSpec::operator->() const {
  return m_opaque_up.get();
}

const lldb_private::FileSpec *SBFileSpec::get() const {
  return m_opaque_up.get();
}

const lldb_private::FileSpec &SBFileSpec::operator*() const {
  return *m_opaque_up;
}

const lldb_private::FileSpec &SBFileSpec::ref() const { return *m_opaque_up; }

void SBFileSpec::SetFileSpec(const lldb_private::FileSpec &fs) {
  *m_opaque_up = fs;
}

bool SBFileSpec::GetDescription(SBStream &description) const {
  LLDB_RECORD_METHOD_CONST(bool, SBFileSpec, GetDescription, (lldb::SBStream &),
                           description);

  Stream &strm = description.ref();
  char path[PATH_MAX];
  if (m_opaque_up->GetPath(path, sizeof(path)))
    strm.PutCString(path);
  return true;
}

void SBFileSpec::AppendPathComponent(const char *fn) {
  LLDB_RECORD_METHOD(void, SBFileSpec, AppendPathComponent, (const char *), fn);

  m_opaque_up->AppendPathComponent(fn);
}

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBFileSpec>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBFileSpec, ());
  LLDB_REGISTER_CONSTRUCTOR(SBFileSpec, (const lldb::SBFileSpec &));
  LLDB_REGISTER_CONSTRUCTOR(SBFileSpec, (const char *));
  LLDB_REGISTER_CONSTRUCTOR(SBFileSpec, (const char *, bool));
  LLDB_REGISTER_METHOD(const lldb::SBFileSpec &,
                       SBFileSpec, operator=,(const lldb::SBFileSpec &));
  LLDB_REGISTER_METHOD_CONST(bool,
                             SBFileSpec, operator==,(const lldb::SBFileSpec &));
  LLDB_REGISTER_METHOD_CONST(bool,
                             SBFileSpec, operator!=,(const lldb::SBFileSpec &));
  LLDB_REGISTER_METHOD_CONST(bool, SBFileSpec, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBFileSpec, operator bool, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBFileSpec, Exists, ());
  LLDB_REGISTER_METHOD(bool, SBFileSpec, ResolveExecutableLocation, ());
  LLDB_REGISTER_STATIC_METHOD(int, SBFileSpec, ResolvePath,
                              (const char *, char *, size_t));
  LLDB_REGISTER_METHOD_CONST(const char *, SBFileSpec, GetFilename, ());
  LLDB_REGISTER_METHOD_CONST(const char *, SBFileSpec, GetDirectory, ());
  LLDB_REGISTER_METHOD(void, SBFileSpec, SetFilename, (const char *));
  LLDB_REGISTER_METHOD(void, SBFileSpec, SetDirectory, (const char *));
  LLDB_REGISTER_METHOD_CONST(uint32_t, SBFileSpec, GetPath, (char *, size_t));
  LLDB_REGISTER_METHOD_CONST(bool, SBFileSpec, GetDescription,
                             (lldb::SBStream &));
  LLDB_REGISTER_METHOD(void, SBFileSpec, AppendPathComponent, (const char *));
}

}
}
