//===-- 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;
    stream_file->GetFile().Open (path, open_options, File::ePermissionsDefault);

    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();
    }
}
