// 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
