//===-- FileSpec.cpp --------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//


#include "lldb/Host/File.h"

#include <fcntl.h>
#include <stdarg.h>

#include "lldb/Core/Error.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/FileSpec.h"

using namespace lldb;
using namespace lldb_private;

static const char *
GetStreamOpenModeFromOptions (uint32_t options)
{
    if (options & File::eOpenOptionAppend)
    {
        if (options & File::eOpenOptionRead)
        {
            if (options & File::eOpenOptionCanCreateNewOnly)
                return "a+x";
            else
                return "a+";
        }
        else if (options & File::eOpenOptionWrite)
        {
            if (options & File::eOpenOptionCanCreateNewOnly)
                return "ax";
            else
                return "a";
        }
    }
    else if (options & File::eOpenOptionRead && options & File::eOpenOptionWrite)
    {
        if (options & File::eOpenOptionCanCreate)
        {
            if (options & File::eOpenOptionCanCreateNewOnly)
                return "w+x";
            else
                return "w+";
        }
        else
            return "r+";
    }
    else if (options & File::eOpenOptionRead)
    {
        return "r";
    }
    else if (options & File::eOpenOptionWrite)
    {
        return "w";
    }
    return NULL;
}

int File::kInvalidDescriptor = -1;
FILE * File::kInvalidStream = NULL;

File::File(const char *path, uint32_t options, uint32_t permissions) :
    m_descriptor (kInvalidDescriptor),
    m_stream (kInvalidStream),
    m_options (0),
    m_owned (false)
{
    Open (path, options, permissions);
}

File::File (const File &rhs) :
    m_descriptor (kInvalidDescriptor),
    m_stream (kInvalidStream),
    m_options (0),
    m_owned (false)
{
    Duplicate (rhs);
}
    

File &
File::operator = (const File &rhs)
{
    if (this != &rhs)
        Duplicate (rhs);        
    return *this;
}

File::~File()
{
    Close ();
}


int
File::GetDescriptor() const
{
    if (DescriptorIsValid())
        return m_descriptor;

    // Don't open the file descriptor if we don't need to, just get it from the
    // stream if we have one.
    if (StreamIsValid())
        return fileno (m_stream);

    // Invalid descriptor and invalid stream, return invalid descriptor.
    return kInvalidDescriptor;
}

void
File::SetDescriptor (int fd, bool transfer_ownership)
{
    if (IsValid())
        Close();
    m_descriptor = fd;
    m_owned = transfer_ownership;
}


FILE *
File::GetStream ()
{
    if (!StreamIsValid())
    {
        if (DescriptorIsValid())
        {
            const char *mode = GetStreamOpenModeFromOptions (m_options);
            if (mode)
                m_stream = ::fdopen (m_descriptor, mode);
        }
    }
    return m_stream;
}


void
File::SetStream (FILE *fh, bool transfer_ownership)
{
    if (IsValid())
        Close();
    m_stream = fh;
    m_owned = transfer_ownership;
}

Error
File::Duplicate (const File &rhs)
{
    Error error;
    if (IsValid ())
        Close();

    if (rhs.DescriptorIsValid())
    {
        m_descriptor = ::fcntl(rhs.GetDescriptor(), F_DUPFD);
        if (!DescriptorIsValid())
            error.SetErrorToErrno();
        else
        {
            m_options = rhs.m_options;
            m_owned = true;
        }
    }
    else
    {
        error.SetErrorString ("invalid file to duplicate");
    }
    return error;
}

Error
File::Open (const char *path, uint32_t options, uint32_t permissions)
{
    Error error;
    if (IsValid())
        Close ();

    int oflag = 0;
    if (options & eOpenOptionRead && 
        options & eOpenOptionWrite )
        oflag |= O_RDWR;
    else if (options & eOpenOptionRead)
        oflag |= O_RDONLY;
    else if (options & eOpenOptionWrite)
        oflag |= O_WRONLY;
    
    if (options & eOpenOptionNonBlocking)
        oflag |= O_NONBLOCK;

    if (options & eOpenOptionAppend)
        oflag |= O_APPEND;
    else
        oflag |= O_TRUNC;

    if (options & eOpenOptionCanCreate)
        oflag |= O_CREAT;
    
    if (options & eOpenOptionCanCreateNewOnly)
        oflag |= O_CREAT | O_EXCL;
    
    mode_t mode = 0;
    if (permissions & ePermissionsUserRead)     mode |= S_IRUSR;
    if (permissions & ePermissionsUserWrite)    mode |= S_IWUSR;
    if (permissions & ePermissionsUserExecute)  mode |= S_IXUSR;
    if (permissions & ePermissionsGroupRead)    mode |= S_IRGRP;
    if (permissions & ePermissionsGroupWrite)   mode |= S_IWGRP;
    if (permissions & ePermissionsGroupExecute) mode |= S_IXGRP;
    if (permissions & ePermissionsWorldRead)    mode |= S_IROTH;
    if (permissions & ePermissionsWorldWrite)   mode |= S_IWOTH;
    if (permissions & ePermissionsWorldExecute) mode |= S_IXOTH;

    m_descriptor = ::open(path, oflag, mode);
    if (!DescriptorIsValid())
        error.SetErrorToErrno();
    else
        m_owned = true;
    
    return error;
}

Error
File::Close ()
{
    Error error;
    if (IsValid ())
    {
        if (m_owned)
        {
            if (StreamIsValid())
            {
                if (::fclose (m_stream) == EOF)
                    error.SetErrorToErrno();
            }
            
            if (DescriptorIsValid())
            {
                if (::close (m_descriptor) != 0)
                    error.SetErrorToErrno();
            }
        }
        m_descriptor = kInvalidDescriptor;
        m_stream = kInvalidStream;
        m_options = 0;
        m_owned = false;
    }
    return error;
}


Error
File::GetFileSpec (FileSpec &file_spec) const
{
    Error error;
#ifdef LLDB_CONFIG_FCNTL_GETPATH_SUPPORTED
    if (IsValid ())
    {
        char path[PATH_MAX];
        if (::fcntl(GetDescriptor(), F_GETPATH, path) == -1)
            error.SetErrorToErrno();
        else
            file_spec.SetFile (path, false);
    }
    else 
    {
        error.SetErrorString("invalid file handle");
    }
#elif defined(__linux__)
    char proc[64];
    char path[PATH_MAX];
    if (::snprintf(proc, sizeof(proc), "/proc/self/fd/%d", GetDescriptor()) < 0)
        error.SetErrorString ("Cannot resolve file descriptor\n");
    else
    {
        ssize_t len;
        if ((len = ::readlink(proc, path, sizeof(path) - 1)) == -1)
            error.SetErrorToErrno();
        else
        {
            path[len] = '\0';
            file_spec.SetFile (path, false);
        }
    }
#else
    error.SetErrorString ("File::GetFileSpec is not supported on this platform");
#endif

    if (error.Fail())
        file_spec.Clear();
    return error;
}

Error
File::SeekFromStart (off_t& offset)
{
    Error error;
    if (DescriptorIsValid())
    {
        offset = ::lseek (m_descriptor, offset, SEEK_SET);

        if (offset == -1)
            error.SetErrorToErrno();
    }
    else 
    {
        error.SetErrorString("invalid file handle");
    }
    return error;
}

Error
File::SeekFromCurrent (off_t& offset)
{
    Error error;
    if (DescriptorIsValid())
    {
        offset = ::lseek (m_descriptor, offset, SEEK_CUR);
        
        if (offset == -1)
            error.SetErrorToErrno();
    }
    else 
    {
        error.SetErrorString("invalid file handle");
    }
    return error;
}

Error
File::SeekFromEnd (off_t& offset)
{
    Error error;
    if (DescriptorIsValid())
    {
        offset = ::lseek (m_descriptor, offset, SEEK_CUR);
        
        if (offset == -1)
            error.SetErrorToErrno();
    }
    else 
    {
        error.SetErrorString("invalid file handle");
    }
    return error;
}

Error
File::Flush ()
{
    Error error;
    if (StreamIsValid())
    {
        if (::fflush (m_stream) == EOF)
            error.SetErrorToErrno();
    }
    else if (!DescriptorIsValid())
    {
        error.SetErrorString("invalid file handle");
    }
    return error;
}


Error
File::Sync ()
{
    Error error;
    if (DescriptorIsValid())
    {
        if (::fsync (m_descriptor) == -1)
            error.SetErrorToErrno();
    }
    else 
    {
        error.SetErrorString("invalid file handle");
    }
    return error;
}

Error
File::Read (void *buf, size_t &num_bytes)
{
    Error error;
    if (DescriptorIsValid())
    {
        ssize_t bytes_read = ::read (m_descriptor, buf, num_bytes);
        if (bytes_read == -1)
        {
            error.SetErrorToErrno();
            num_bytes = 0;
        }
        else
            num_bytes = bytes_read;
    }
    else if (StreamIsValid())
    {
        size_t bytes_read = ::fread (buf, 1, num_bytes, m_stream);
        if (bytes_read == 0)
        {
            if (::feof(m_stream))
                error.SetErrorString ("feof");
            else if (::ferror (m_stream))
                error.SetErrorString ("ferror");
            num_bytes = 0;
        }
        else
            num_bytes = bytes_read;
    }
    else 
    {
        num_bytes = 0;
        error.SetErrorString("invalid file handle");
    }
    return error;
}
          
Error
File::Write (const void *buf, size_t &num_bytes)
{
    Error error;
    if (DescriptorIsValid())
    {
        ssize_t bytes_written = ::write (m_descriptor, buf, num_bytes);
        if (bytes_written == -1)
        {
            error.SetErrorToErrno();
            num_bytes = 0;
        }
        else
            num_bytes = bytes_written;
    }
    else if (StreamIsValid())
    {
        size_t bytes_written = ::fwrite (buf, 1, num_bytes, m_stream);
        if (bytes_written == 0)
        {
            if (::feof(m_stream))
                error.SetErrorString ("feof");
            else if (::ferror (m_stream))
                error.SetErrorString ("ferror");
            num_bytes = 0;
        }
        else
            num_bytes = bytes_written;
        
    }
    else 
    {
        num_bytes = 0;
        error.SetErrorString("invalid file handle");
    }
    return error;
}


Error
File::Read (void *buf, size_t &num_bytes, off_t &offset)
{
    Error error;
    int fd = GetDescriptor();
    if (fd != kInvalidDescriptor)
    {
        ssize_t bytes_read = ::pread (fd, buf, num_bytes, offset);
        if (bytes_read < 0)
        {
            num_bytes = 0;
            error.SetErrorToErrno();
        }
        else
        {
            offset += bytes_read;
            num_bytes = bytes_read;
        }
    }
    else 
    {
        num_bytes = 0;
        error.SetErrorString("invalid file handle");
    }
    return error;
}

Error
File::Write (const void *buf, size_t &num_bytes, off_t &offset)
{
    Error error;
    int fd = GetDescriptor();
    if (fd != kInvalidDescriptor)
    {
        ssize_t bytes_written = ::pwrite (m_descriptor, buf, num_bytes, offset);
        if (bytes_written < 0)
        {
            num_bytes = 0;
            error.SetErrorToErrno();
        }
        else
        {
            offset += bytes_written;
            num_bytes = bytes_written;
        }
    }
    else 
    {
        num_bytes = 0;
        error.SetErrorString("invalid file handle");
    }
    return error;
}

//------------------------------------------------------------------
// Print some formatted output to the stream.
//------------------------------------------------------------------
int
File::Printf (const char *format, ...)
{
    va_list args;
    va_start (args, format);
    int result = PrintfVarArg (format, args);
    va_end (args);
    return result;
}

//------------------------------------------------------------------
// Print some formatted output to the stream.
//------------------------------------------------------------------
int
File::PrintfVarArg (const char *format, va_list args)
{
    int result = 0;
    if (DescriptorIsValid())
    {
        char *s = NULL;
        result = vasprintf(&s, format, args);
        if (s != NULL)
        {
            if (result > 0)
            {
                size_t s_len = result;
                Write (s, s_len);
                result = s_len;
            }
            free (s);
        }
    }
    else if (StreamIsValid())
    {
        result = ::vfprintf (m_stream, format, args);
    }
    return result;
}
