// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "fxcrt_posix.h"

#include "core/include/fxcrt/fx_basic.h"

#if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || \
    _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || \
    _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
IFXCRT_FileAccess* FXCRT_FileAccess_Create() {
  return new CFXCRT_FileAccess_Posix;
}
void FXCRT_Posix_GetFileMode(FX_DWORD dwModes,
                             int32_t& nFlags,
                             int32_t& nMasks) {
  nFlags = O_BINARY | O_LARGEFILE;
  if (dwModes & FX_FILEMODE_ReadOnly) {
    nFlags |= O_RDONLY;
    nMasks = 0;
  } else {
    nFlags |= O_RDWR | O_CREAT;
    if (dwModes & FX_FILEMODE_Truncate) {
      nFlags |= O_TRUNC;
    }
    nMasks = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
  }
}
CFXCRT_FileAccess_Posix::CFXCRT_FileAccess_Posix() : m_nFD(-1) {}
CFXCRT_FileAccess_Posix::~CFXCRT_FileAccess_Posix() {
  Close();
}
FX_BOOL CFXCRT_FileAccess_Posix::Open(const CFX_ByteStringC& fileName,
                                      FX_DWORD dwMode) {
  if (m_nFD > -1) {
    return FALSE;
  }
  int32_t nFlags, nMasks;
  FXCRT_Posix_GetFileMode(dwMode, nFlags, nMasks);
  m_nFD = open(fileName.GetCStr(), nFlags, nMasks);
  return m_nFD > -1;
}
FX_BOOL CFXCRT_FileAccess_Posix::Open(const CFX_WideStringC& fileName,
                                      FX_DWORD dwMode) {
  return Open(FX_UTF8Encode(fileName), dwMode);
}
void CFXCRT_FileAccess_Posix::Close() {
  if (m_nFD < 0) {
    return;
  }
  close(m_nFD);
  m_nFD = -1;
}
void CFXCRT_FileAccess_Posix::Release() {
  delete this;
}
FX_FILESIZE CFXCRT_FileAccess_Posix::GetSize() const {
  if (m_nFD < 0) {
    return 0;
  }
  struct stat s;
  FXSYS_memset(&s, 0, sizeof(s));
  fstat(m_nFD, &s);
  return s.st_size;
}
FX_FILESIZE CFXCRT_FileAccess_Posix::GetPosition() const {
  if (m_nFD < 0) {
    return (FX_FILESIZE)-1;
  }
  return lseek(m_nFD, 0, SEEK_CUR);
}
FX_FILESIZE CFXCRT_FileAccess_Posix::SetPosition(FX_FILESIZE pos) {
  if (m_nFD < 0) {
    return (FX_FILESIZE)-1;
  }
  return lseek(m_nFD, pos, SEEK_SET);
}
size_t CFXCRT_FileAccess_Posix::Read(void* pBuffer, size_t szBuffer) {
  if (m_nFD < 0) {
    return 0;
  }
  return read(m_nFD, pBuffer, szBuffer);
}
size_t CFXCRT_FileAccess_Posix::Write(const void* pBuffer, size_t szBuffer) {
  if (m_nFD < 0) {
    return 0;
  }
  return write(m_nFD, pBuffer, szBuffer);
}
size_t CFXCRT_FileAccess_Posix::ReadPos(void* pBuffer,
                                        size_t szBuffer,
                                        FX_FILESIZE pos) {
  if (m_nFD < 0) {
    return 0;
  }
  if (pos >= GetSize()) {
    return 0;
  }
  if (SetPosition(pos) == (FX_FILESIZE)-1) {
    return 0;
  }
  return Read(pBuffer, szBuffer);
}
size_t CFXCRT_FileAccess_Posix::WritePos(const void* pBuffer,
                                         size_t szBuffer,
                                         FX_FILESIZE pos) {
  if (m_nFD < 0) {
    return 0;
  }
  if (SetPosition(pos) == (FX_FILESIZE)-1) {
    return 0;
  }
  return Write(pBuffer, szBuffer);
}
FX_BOOL CFXCRT_FileAccess_Posix::Flush() {
  if (m_nFD < 0) {
    return FALSE;
  }
  return fsync(m_nFD) > -1;
}
FX_BOOL CFXCRT_FileAccess_Posix::Truncate(FX_FILESIZE szFile) {
  if (m_nFD < 0) {
    return FALSE;
  }
  return !ftruncate(m_nFD, szFile);
}
FX_BOOL FX_File_Exist(const CFX_ByteStringC& fileName) {
  return access(fileName.GetCStr(), F_OK) > -1;
}
FX_BOOL FX_File_Exist(const CFX_WideStringC& fileName) {
  return FX_File_Exist(FX_UTF8Encode(fileName));
}
FX_BOOL FX_File_Delete(const CFX_ByteStringC& fileName) {
  return remove(fileName.GetCStr()) > -1;
}
FX_BOOL FX_File_Delete(const CFX_WideStringC& fileName) {
  return FX_File_Delete(FX_UTF8Encode(fileName));
}
FX_BOOL FX_File_Copy(const CFX_ByteStringC& fileNameSrc,
                     const CFX_ByteStringC& fileNameDst) {
  CFXCRT_FileAccess_Posix src, dst;
  if (!src.Open(fileNameSrc, FX_FILEMODE_ReadOnly)) {
    return FALSE;
  }
  FX_FILESIZE size = src.GetSize();
  if (!size) {
    return FALSE;
  }
  if (!dst.Open(fileNameDst, FX_FILEMODE_Truncate)) {
    return FALSE;
  }
  size_t num = 0;
  uint8_t* pBuffer = FX_Alloc(uint8_t, 32768);
  num = src.Read(pBuffer, 32768);
  while (num) {
    if (dst.Write(pBuffer, num) != num) {
      break;
    }
    num = src.Read(pBuffer, 32768);
  }
  FX_Free(pBuffer);
  return TRUE;
}
FX_BOOL FX_File_Copy(const CFX_WideStringC& fileNameSrc,
                     const CFX_WideStringC& fileNameDst) {
  return FX_File_Copy(FX_UTF8Encode(fileNameSrc), FX_UTF8Encode(fileNameDst));
}
FX_BOOL FX_File_Move(const CFX_ByteStringC& fileNameSrc,
                     const CFX_ByteStringC& fileNameDst) {
  return rename(fileNameSrc.GetCStr(), fileNameDst.GetCStr());
}
FX_BOOL FX_File_Move(const CFX_WideStringC& fileNameSrc,
                     const CFX_WideStringC& fileNameDst) {
  return FX_File_Move(FX_UTF8Encode(fileNameSrc), FX_UTF8Encode(fileNameDst));
}
#endif
