// 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 "../../include/fxcrt/fx_ext.h"
#include "fxcrt_posix.h"
#if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
IFXCRT_FileAccess* FXCRT_FileAccess_Create(IFX_Allocator* pAllocator)
{
    if (pAllocator) {
        return FX_NewAtAllocator(pAllocator) CFXCRT_FileAccess_Posix();
    } else {
        return FX_NEW CFXCRT_FileAccess_Posix;
    }
}
void FXCRT_Posix_GetFileMode(FX_DWORD dwModes, FX_INT32 &nFlags, FX_INT32 &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(FX_BSTR fileName, FX_DWORD dwMode)
{
    if (m_nFD > -1) {
        return FALSE;
    }
    FX_INT32 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(FX_WSTR 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(IFX_Allocator* pAllocator)
{
    if (pAllocator) {
        FX_DeleteAtAllocator(this, pAllocator, CFXCRT_FileAccess_Posix);
    } else {
        delete this;
    }
}
FX_FILESIZE CFXCRT_FileAccess_Posix::GetSize() const
{
    if (m_nFD < 0) {
        return 0;
    }
    struct stat s;
    FXSYS_memset32(&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(FX_BSTR fileName)
{
    return access(fileName.GetCStr(), F_OK) > -1;
}
FX_BOOL FX_File_Exist(FX_WSTR fileName)
{
    return FX_File_Exist(FX_UTF8Encode(fileName));
}
FX_BOOL FX_File_Delete(FX_BSTR fileName)
{
    return remove(fileName.GetCStr()) > -1;
}
FX_BOOL FX_File_Delete(FX_WSTR fileName)
{
    return FX_File_Delete(FX_UTF8Encode(fileName));
}
FX_BOOL FX_File_Copy(FX_BSTR fileNameSrc, FX_BSTR 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;
    FX_LPBYTE pBuffer = FX_Alloc(FX_BYTE, 32768);
    if (!pBuffer) {
        return FALSE;
    }
    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(FX_WSTR fileNameSrc, FX_WSTR fileNameDst)
{
    return FX_File_Copy(FX_UTF8Encode(fileNameSrc), FX_UTF8Encode(fileNameDst));
}
FX_BOOL FX_File_Move(FX_BSTR fileNameSrc, FX_BSTR fileNameDst)
{
    return rename(fileNameSrc.GetCStr(), fileNameDst.GetCStr());
}
FX_BOOL FX_File_Move(FX_WSTR fileNameSrc, FX_WSTR fileNameDst)
{
    return FX_File_Move(FX_UTF8Encode(fileNameSrc), FX_UTF8Encode(fileNameDst));
}
#endif
