//===-- SBStream.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/API/SBStream.h"

#include "lldb/Core/Error.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"

using namespace lldb;
using namespace lldb_private;

SBStream::SBStream () :
    m_opaque_ap (new StreamString()),
    m_is_file (false)
{
}

SBStream::~SBStream ()
{
}

bool
SBStream::IsValid() const
{
    return (m_opaque_ap.get() != NULL);
}

// If this stream is not redirected to a file, it will maintain a local
// cache for the stream data which can be accessed using this accessor.
const char *
SBStream::GetData ()
{
    if (m_is_file || m_opaque_ap.get() == NULL)
        return NULL;
    
    return static_cast<StreamString *>(m_opaque_ap.get())->GetData();
}

// If this stream is not redirected to a file, it will maintain a local
// cache for the stream output whose length can be accessed using this 
// accessor.
size_t
SBStream::GetSize()
{
    if (m_is_file || m_opaque_ap.get() == NULL)
        return 0;
    
    return static_cast<StreamString *>(m_opaque_ap.get())->GetSize();
}

void
SBStream::Printf (const char *format, ...)
{
    if (!format)
        return;
    va_list args;
    va_start (args, format);
    ref().PrintfVarArg (format, args);
    va_end (args);
}

void
SBStream::RedirectToFile (const char *path, bool append)
{
    std::string local_data;
    if (m_opaque_ap.get())
    {
        // See if we have any locally backed data. If so, copy it so we can then
        // redirect it to the file so we don't lose the data
        if (!m_is_file)
            local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
    }
    StreamFile *stream_file = new StreamFile;
    uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
    if (append)
        open_options |= File::eOpenOptionAppend;
    else
        open_options |= File::eOpenOptionTruncate;
    stream_file->GetFile().Open (path, open_options, lldb::eFilePermissionsFileDefault);

    m_opaque_ap.reset (stream_file);

    if (m_opaque_ap.get())
    {
        m_is_file = true;

        // If we had any data locally in our StreamString, then pass that along to 
        // the to new file we are redirecting to.
        if (!local_data.empty())
            m_opaque_ap->Write (&local_data[0], local_data.size());
    }
    else
        m_is_file = false;
}

void
SBStream::RedirectToFileHandle (FILE *fh, bool transfer_fh_ownership)
{
    std::string local_data;
    if (m_opaque_ap.get())
    {
        // See if we have any locally backed data. If so, copy it so we can then
        // redirect it to the file so we don't lose the data
        if (!m_is_file)
            local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
    }
    m_opaque_ap.reset (new StreamFile (fh, transfer_fh_ownership));

    if (m_opaque_ap.get())
    {
        m_is_file = true;

        // If we had any data locally in our StreamString, then pass that along to 
        // the to new file we are redirecting to.
        if (!local_data.empty())
            m_opaque_ap->Write (&local_data[0], local_data.size());
    }
    else
        m_is_file = false;
}

void
SBStream::RedirectToFileDescriptor (int fd, bool transfer_fh_ownership)
{
    std::string local_data;
    if (m_opaque_ap.get())
    {
        // See if we have any locally backed data. If so, copy it so we can then
        // redirect it to the file so we don't lose the data
        if (!m_is_file)
            local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
    }

    m_opaque_ap.reset (new StreamFile (::fdopen (fd, "w"), transfer_fh_ownership));
    if (m_opaque_ap.get())
    {
        m_is_file = true;

        // If we had any data locally in our StreamString, then pass that along to 
        // the to new file we are redirecting to.
        if (!local_data.empty())
            m_opaque_ap->Write (&local_data[0], local_data.size());
    }
    else
        m_is_file = false;

}

lldb_private::Stream *
SBStream::operator->()
{
    return m_opaque_ap.get();
}

lldb_private::Stream *
SBStream::get()
{
    return m_opaque_ap.get();
}

lldb_private::Stream &
SBStream::ref()
{
    if (m_opaque_ap.get() == NULL)
        m_opaque_ap.reset (new StreamString());
    return *m_opaque_ap.get();
}

void
SBStream::Clear ()
{
    if (m_opaque_ap.get())
    {
        // See if we have any locally backed data. If so, copy it so we can then
        // redirect it to the file so we don't lose the data
        if (m_is_file)
            m_opaque_ap.reset();
        else
            static_cast<StreamString *>(m_opaque_ap.get())->GetString().clear();
    }
}
