//===-- SBFile.cpp --------------------------------------------------------===//
//
// 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/SBFile.h"
#include "lldb/API/SBError.h"
#include "lldb/Host/File.h"
#include "lldb/Utility/Instrumentation.h"

#ifdef _WIN32
#include <io.h>
#endif

using namespace lldb;
using namespace lldb_private;

SBFile::~SBFile() = default;

SBFile::SBFile(FileSP file_sp) : m_opaque_sp(file_sp) {
  // We have no way to capture the incoming FileSP as the class isn't
  // instrumented, so pretend that it's always null.
  LLDB_INSTRUMENT_VA(this, file_sp);
}

SBFile::SBFile(const SBFile &rhs) : m_opaque_sp(rhs.m_opaque_sp) {
  LLDB_INSTRUMENT_VA(this, rhs);
}

SBFile &SBFile ::operator=(const SBFile &rhs) {
  LLDB_INSTRUMENT_VA(this, rhs);

  if (this != &rhs)
    m_opaque_sp = rhs.m_opaque_sp;
  return *this;
}

SBFile::SBFile() { LLDB_INSTRUMENT_VA(this); }

SBFile::SBFile(FILE *file, bool transfer_ownership) {
  LLDB_INSTRUMENT_VA(this, file, transfer_ownership);

  // For backwards comptability, this defaulted to ReadOnly previously.
  m_opaque_sp = std::make_shared<NativeFile>(file, File::eOpenOptionReadOnly,
                                             transfer_ownership);
}

SBFile::SBFile(FILE *file, const char *mode, bool transfer_ownership) {
  LLDB_INSTRUMENT_VA(this, file, transfer_ownership);

  auto options = File::GetOptionsFromMode(mode);
  if (!options) {
    llvm::consumeError(options.takeError());
    return;
  }

  m_opaque_sp =
      std::make_shared<NativeFile>(file, options.get(), transfer_ownership);
}

SBFile::SBFile(int fd, const char *mode, bool transfer_ownership) {
  LLDB_INSTRUMENT_VA(this, fd, mode, transfer_ownership);

  auto options = File::GetOptionsFromMode(mode);
  if (!options) {
    llvm::consumeError(options.takeError());
    return;
  }
  m_opaque_sp =
      std::make_shared<NativeFile>(fd, options.get(), transfer_ownership);
}

int SBFile::OpenFdFromHandle(intptr_t handle, int flags) {
#ifdef _WIN32
  return _open_osfhandle(handle, flags);
#else
  (void)handle;
  (void)flags;
  return -1;
#endif
}

SBError SBFile::Read(uint8_t *buf, size_t num_bytes, size_t *bytes_read) {
  LLDB_INSTRUMENT_VA(this, buf, num_bytes, bytes_read);

  SBError error;
  if (!m_opaque_sp) {
    error = Status::FromErrorString("invalid SBFile");
    *bytes_read = 0;
  } else {
    error.SetError(m_opaque_sp->Read(buf, num_bytes));
    *bytes_read = num_bytes;
  }
  return error;
}

SBError SBFile::Write(const uint8_t *buf, size_t num_bytes,
                      size_t *bytes_written) {
  LLDB_INSTRUMENT_VA(this, buf, num_bytes, bytes_written);

  SBError error;
  if (!m_opaque_sp) {
    error = Status::FromErrorString("invalid SBFile");
    *bytes_written = 0;
  } else {
    error.SetError(m_opaque_sp->Write(buf, num_bytes));
    *bytes_written = num_bytes;
  }
  return error;
}

SBError SBFile::Flush() {
  LLDB_INSTRUMENT_VA(this);

  SBError error;
  if (!m_opaque_sp) {
    error = Status::FromErrorString("invalid SBFile");
  } else {
    error.SetError(m_opaque_sp->Flush());
  }
  return error;
}

bool SBFile::IsValid() const {
  LLDB_INSTRUMENT_VA(this);
  return m_opaque_sp && m_opaque_sp->IsValid();
}

SBError SBFile::Close() {
  LLDB_INSTRUMENT_VA(this);
  SBError error;
  if (m_opaque_sp)
    error.SetError(m_opaque_sp->Close());
  return error;
}

SBFile::operator bool() const {
  LLDB_INSTRUMENT_VA(this);
  return IsValid();
}

bool SBFile::operator!() const {
  LLDB_INSTRUMENT_VA(this);
  return !IsValid();
}

FileSP SBFile::GetFile() const {
  LLDB_INSTRUMENT_VA(this);
  return m_opaque_sp;
}
