//===-- StringPrinter.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/DataFormatters/StringPrinter.h"

#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"

#include "llvm/Support/ConvertUTF.h"

#include <ctype.h>
#include <locale>

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;

// we define this for all values of type but only implement it for those we care about
// that's good because we get linker errors for any unsupported type
template <lldb_private::formatters::StringPrinter::StringElementType type>
static StringPrinter::StringPrinterBufferPointer<>
GetPrintableImpl(uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next);

// mimic isprint() for Unicode codepoints
static bool
isprint(char32_t codepoint)
{
    if (codepoint <= 0x1F || codepoint == 0x7F) // C0
    {
        return false;
    }
    if (codepoint >= 0x80 && codepoint <= 0x9F) // C1
    {
        return false;
    }
    if (codepoint == 0x2028 || codepoint == 0x2029) // line/paragraph separators
    {
        return false;
    }
    if (codepoint == 0x200E || codepoint == 0x200F || (codepoint >= 0x202A && codepoint <= 0x202E)) // bidirectional text control
    {
        return false;
    }
    if (codepoint >= 0xFFF9 && codepoint <= 0xFFFF) // interlinears and generally specials
    {
        return false;
    }
    return true;
}

template <>
StringPrinter::StringPrinterBufferPointer<>
GetPrintableImpl<StringPrinter::StringElementType::ASCII> (uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next)
{
    StringPrinter::StringPrinterBufferPointer<> retval = {nullptr};
    
    switch (*buffer)
    {
        case 0:
            retval = {"\\0",2};
            break;
        case '\a':
            retval = {"\\a",2};
            break;
        case '\b':
            retval = {"\\b",2};
            break;
        case '\f':
            retval = {"\\f",2};
            break;
        case '\n':
            retval = {"\\n",2};
            break;
        case '\r':
            retval = {"\\r",2};
            break;
        case '\t':
            retval = {"\\t",2};
            break;
        case '\v':
            retval = {"\\v",2};
            break;
        case '\"':
            retval = {"\\\"",2};
            break;
        case '\\':
            retval = {"\\\\",2};
            break;
        default:
          if (isprint(*buffer))
              retval = {buffer,1};
          else
          {
              uint8_t* data = new uint8_t[5];
              sprintf((char*)data,"\\x%02x",*buffer);
              retval = {data, 4, [] (const uint8_t* c) {delete[] c;} };
              break;
          }
    }
    
    next = buffer + 1;
    return retval;
}

static char32_t
ConvertUTF8ToCodePoint (unsigned char c0, unsigned char c1)
{
    return (c0-192)*64+(c1-128);
}
static char32_t
ConvertUTF8ToCodePoint (unsigned char c0, unsigned char c1, unsigned char c2)
{
    return (c0-224)*4096+(c1-128)*64+(c2-128);
}
static char32_t
ConvertUTF8ToCodePoint (unsigned char c0, unsigned char c1, unsigned char c2, unsigned char c3)
{
    return (c0-240)*262144+(c2-128)*4096+(c2-128)*64+(c3-128);
}

template <>
StringPrinter::StringPrinterBufferPointer<>
GetPrintableImpl<StringPrinter::StringElementType::UTF8> (uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next)
{
    StringPrinter::StringPrinterBufferPointer<> retval {nullptr};
    
    unsigned utf8_encoded_len = getNumBytesForUTF8(*buffer);
    
    if (1+buffer_end-buffer < utf8_encoded_len)
    {
        // I don't have enough bytes - print whatever I have left
        retval = {buffer,static_cast<size_t>(1+buffer_end-buffer)};
        next = buffer_end+1;
        return retval;
    }
    
    char32_t codepoint = 0;
    switch (utf8_encoded_len)
    {
        case 1:
            // this is just an ASCII byte - ask ASCII
            return GetPrintableImpl<StringPrinter::StringElementType::ASCII>(buffer, buffer_end, next);
        case 2:
            codepoint = ConvertUTF8ToCodePoint((unsigned char)*buffer, (unsigned char)*(buffer+1));
            break;
        case 3:
            codepoint = ConvertUTF8ToCodePoint((unsigned char)*buffer, (unsigned char)*(buffer+1), (unsigned char)*(buffer+2));
            break;
        case 4:
            codepoint = ConvertUTF8ToCodePoint((unsigned char)*buffer, (unsigned char)*(buffer+1), (unsigned char)*(buffer+2), (unsigned char)*(buffer+3));
            break;
        default:
            // this is probably some bogus non-character thing
            // just print it as-is and hope to sync up again soon
            retval = {buffer,1};
            next = buffer+1;
            return retval;
    }
    
    if (codepoint)
    {
        switch (codepoint)
        {
            case 0:
                retval = {"\\0",2};
                break;
            case '\a':
                retval = {"\\a",2};
                break;
            case '\b':
                retval = {"\\b",2};
                break;
            case '\f':
                retval = {"\\f",2};
                break;
            case '\n':
                retval = {"\\n",2};
                break;
            case '\r':
                retval = {"\\r",2};
                break;
            case '\t':
                retval = {"\\t",2};
                break;
            case '\v':
                retval = {"\\v",2};
                break;
            case '\"':
                retval = {"\\\"",2};
                break;
            case '\\':
                retval = {"\\\\",2};
                break;
            default:
                if (isprint(codepoint))
                    retval = {buffer,utf8_encoded_len};
                else
                {
                    uint8_t* data = new uint8_t[11];
                    sprintf((char*)data,"\\U%08x",codepoint);
                    retval = { data,10,[] (const uint8_t* c) {delete[] c;} };
                    break;
                }
        }
        
        next = buffer + utf8_encoded_len;
        return retval;
    }
    
    // this should not happen - but just in case.. try to resync at some point
    retval = {buffer,1};
    next = buffer+1;
    return retval;
}

// Given a sequence of bytes, this function returns:
// a sequence of bytes to actually print out + a length
// the following unscanned position of the buffer is in next
static StringPrinter::StringPrinterBufferPointer<>
GetPrintable(StringPrinter::StringElementType type, uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next)
{
    if (!buffer)
        return {nullptr};
    
    switch (type)
    {
        case StringPrinter::StringElementType::ASCII:
            return GetPrintableImpl<StringPrinter::StringElementType::ASCII>(buffer, buffer_end, next);
        case StringPrinter::StringElementType::UTF8:
            return GetPrintableImpl<StringPrinter::StringElementType::UTF8>(buffer, buffer_end, next);
        default:
            return {nullptr};
    }
}

StringPrinter::EscapingHelper
StringPrinter::GetDefaultEscapingHelper (GetPrintableElementType elem_type)
{
    switch (elem_type)
    {
        case GetPrintableElementType::UTF8:
            return [] (uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next) -> StringPrinter::StringPrinterBufferPointer<> {
                return GetPrintable(StringPrinter::StringElementType::UTF8, buffer, buffer_end, next);
            };
        case GetPrintableElementType::ASCII:
            return [] (uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next) -> StringPrinter::StringPrinterBufferPointer<> {
                return GetPrintable(StringPrinter::StringElementType::ASCII, buffer, buffer_end, next);
            };
    }
    llvm_unreachable("bad element type");
}

// use this call if you already have an LLDB-side buffer for the data
template<typename SourceDataType>
static bool
DumpUTFBufferToStream (ConversionResult (*ConvertFunction) (const SourceDataType**,
                                                            const SourceDataType*,
                                                            UTF8**,
                                                            UTF8*,
                                                            ConversionFlags),
                       const StringPrinter::ReadBufferAndDumpToStreamOptions& dump_options)
{
    Stream &stream(*dump_options.GetStream());
    if (dump_options.GetPrefixToken() != 0)
        stream.Printf("%s",dump_options.GetPrefixToken());
    if (dump_options.GetQuote() != 0)
        stream.Printf("%c",dump_options.GetQuote());
    auto data(dump_options.GetData());
    auto source_size(dump_options.GetSourceSize());
    if (data.GetByteSize() && data.GetDataStart() && data.GetDataEnd())
    {
        const int bufferSPSize = data.GetByteSize();
        if (dump_options.GetSourceSize() == 0)
        {
            const int origin_encoding = 8*sizeof(SourceDataType);
            source_size = bufferSPSize/(origin_encoding / 4);
        }
        
        const SourceDataType *data_ptr = (const SourceDataType*)data.GetDataStart();
        const SourceDataType *data_end_ptr = data_ptr + source_size;
        
        const bool zero_is_terminator = dump_options.GetBinaryZeroIsTerminator();
        
        if (zero_is_terminator)
        {
            while (data_ptr < data_end_ptr)
            {
                if (!*data_ptr)
                {
                    data_end_ptr = data_ptr;
                    break;
                }
                data_ptr++;
            }
            
            data_ptr = (const SourceDataType*)data.GetDataStart();
        }
        
        lldb::DataBufferSP utf8_data_buffer_sp;
        UTF8* utf8_data_ptr = nullptr;
        UTF8* utf8_data_end_ptr = nullptr;
        
        if (ConvertFunction)
        {
            utf8_data_buffer_sp.reset(new DataBufferHeap(4*bufferSPSize,0));
            utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes();
            utf8_data_end_ptr = utf8_data_ptr + utf8_data_buffer_sp->GetByteSize();
            ConvertFunction ( &data_ptr, data_end_ptr, &utf8_data_ptr, utf8_data_end_ptr, lenientConversion );
            if (false == zero_is_terminator)
                utf8_data_end_ptr = utf8_data_ptr;
            utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes(); // needed because the ConvertFunction will change the value of the data_ptr
        }
        else
        {
            // just copy the pointers - the cast is necessary to make the compiler happy
            // but this should only happen if we are reading UTF8 data
            utf8_data_ptr = const_cast<UTF8 *>(reinterpret_cast<const UTF8*>(data_ptr));
            utf8_data_end_ptr = const_cast<UTF8 *>(reinterpret_cast<const UTF8*>(data_end_ptr));
        }
        
        const bool escape_non_printables = dump_options.GetEscapeNonPrintables();
        lldb_private::formatters::StringPrinter::EscapingHelper escaping_callback;
        if (escape_non_printables)
        {
            if (Language *language = Language::FindPlugin(dump_options.GetLanguage()))
                escaping_callback = language->GetStringPrinterEscapingHelper(lldb_private::formatters::StringPrinter::GetPrintableElementType::UTF8);
            else
                escaping_callback = lldb_private::formatters::StringPrinter::GetDefaultEscapingHelper(lldb_private::formatters::StringPrinter::GetPrintableElementType::UTF8);
        }
        
        // since we tend to accept partial data (and even partially malformed data)
        // we might end up with no NULL terminator before the end_ptr
        // hence we need to take a slower route and ensure we stay within boundaries
        for (;utf8_data_ptr < utf8_data_end_ptr;)
        {
            if (zero_is_terminator && !*utf8_data_ptr)
                break;
            
            if (escape_non_printables)
            {
                uint8_t* next_data = nullptr;
                auto printable = escaping_callback(utf8_data_ptr, utf8_data_end_ptr, next_data);
                auto printable_bytes = printable.GetBytes();
                auto printable_size = printable.GetSize();
                if (!printable_bytes || !next_data)
                {
                    // GetPrintable() failed on us - print one byte in a desperate resync attempt
                    printable_bytes = utf8_data_ptr;
                    printable_size = 1;
                    next_data = utf8_data_ptr+1;
                }
                for (unsigned c = 0; c < printable_size; c++)
                    stream.Printf("%c", *(printable_bytes+c));
                utf8_data_ptr = (uint8_t*)next_data;
            }
            else
            {
                stream.Printf("%c",*utf8_data_ptr);
                utf8_data_ptr++;
            }
        }
    }
    if (dump_options.GetQuote() != 0)
        stream.Printf("%c",dump_options.GetQuote());
    if (dump_options.GetSuffixToken() != 0)
        stream.Printf("%s",dump_options.GetSuffixToken());
    if (dump_options.GetIsTruncated())
        stream.Printf("...");
    return true;
}

lldb_private::formatters::StringPrinter::ReadStringAndDumpToStreamOptions::ReadStringAndDumpToStreamOptions (ValueObject& valobj) :
    ReadStringAndDumpToStreamOptions()
{
    SetEscapeNonPrintables(valobj.GetTargetSP()->GetDebugger().GetEscapeNonPrintables());
}

lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStreamOptions::ReadBufferAndDumpToStreamOptions (ValueObject& valobj) :
    ReadBufferAndDumpToStreamOptions()
{
    SetEscapeNonPrintables(valobj.GetTargetSP()->GetDebugger().GetEscapeNonPrintables());
}

lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStreamOptions::ReadBufferAndDumpToStreamOptions (const ReadStringAndDumpToStreamOptions& options) :
    ReadBufferAndDumpToStreamOptions()
{
    SetStream(options.GetStream());
    SetPrefixToken(options.GetPrefixToken());
    SetSuffixToken(options.GetSuffixToken());
    SetQuote(options.GetQuote());
    SetEscapeNonPrintables(options.GetEscapeNonPrintables());
    SetBinaryZeroIsTerminator(options.GetBinaryZeroIsTerminator());
    SetLanguage(options.GetLanguage());
}


namespace lldb_private
{

namespace formatters
{

template <>
bool
StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII> (const ReadStringAndDumpToStreamOptions& options)
{
    assert(options.GetStream() && "need a Stream to print the string to");
    Error my_error;

    ProcessSP process_sp(options.GetProcessSP());

    if (process_sp.get() == nullptr || options.GetLocation() == 0)
        return false;

    size_t size;
    const auto max_size = process_sp->GetTarget().GetMaximumSizeOfStringSummary();
    bool is_truncated = false;

    if (options.GetSourceSize() == 0)
        size = max_size;
    else if (!options.GetIgnoreMaxLength())
    {
        size = options.GetSourceSize();
        if (size > max_size)
        {
            size = max_size;
            is_truncated = true;
        }
    }
    else
        size = options.GetSourceSize();

    lldb::DataBufferSP buffer_sp(new DataBufferHeap(size,0));

    process_sp->ReadCStringFromMemory(options.GetLocation(), (char*)buffer_sp->GetBytes(), size, my_error);

    if (my_error.Fail())
        return false;

    const char* prefix_token = options.GetPrefixToken();
    char quote = options.GetQuote();

    if (prefix_token != 0)
        options.GetStream()->Printf("%s%c",prefix_token,quote);
    else if (quote != 0)
        options.GetStream()->Printf("%c",quote);

    uint8_t* data_end = buffer_sp->GetBytes()+buffer_sp->GetByteSize();

    const bool escape_non_printables = options.GetEscapeNonPrintables();
    lldb_private::formatters::StringPrinter::EscapingHelper escaping_callback;
    if (escape_non_printables)
    {
        if (Language *language = Language::FindPlugin(options.GetLanguage()))
            escaping_callback = language->GetStringPrinterEscapingHelper(lldb_private::formatters::StringPrinter::GetPrintableElementType::ASCII);
        else
            escaping_callback = lldb_private::formatters::StringPrinter::GetDefaultEscapingHelper(lldb_private::formatters::StringPrinter::GetPrintableElementType::ASCII);
    }
    
    // since we tend to accept partial data (and even partially malformed data)
    // we might end up with no NULL terminator before the end_ptr
    // hence we need to take a slower route and ensure we stay within boundaries
    for (uint8_t* data = buffer_sp->GetBytes(); *data && (data < data_end);)
    {
        if (escape_non_printables)
        {
            uint8_t* next_data = nullptr;
            auto printable = escaping_callback(data, data_end, next_data);
            auto printable_bytes = printable.GetBytes();
            auto printable_size = printable.GetSize();
            if (!printable_bytes || !next_data)
            {
                // GetPrintable() failed on us - print one byte in a desperate resync attempt
                printable_bytes = data;
                printable_size = 1;
                next_data = data+1;
            }
            for (unsigned c = 0; c < printable_size; c++)
                options.GetStream()->Printf("%c", *(printable_bytes+c));
            data = (uint8_t*)next_data;
        }
        else
        {
            options.GetStream()->Printf("%c",*data);
            data++;
        }
    }
    
    const char* suffix_token = options.GetSuffixToken();
    
    if (suffix_token != 0)
        options.GetStream()->Printf("%c%s",quote, suffix_token);
    else if (quote != 0)
        options.GetStream()->Printf("%c",quote);

    if (is_truncated)
        options.GetStream()->Printf("...");
    
    return true;
}

template<typename SourceDataType>
static bool
ReadUTFBufferAndDumpToStream (const StringPrinter::ReadStringAndDumpToStreamOptions& options,
                              ConversionResult (*ConvertFunction) (const SourceDataType**,
                                                                   const SourceDataType*,
                                                                   UTF8**,
                                                                   UTF8*,
                                                                   ConversionFlags))
{
    assert(options.GetStream() && "need a Stream to print the string to");

    if (options.GetLocation() == 0 || options.GetLocation() == LLDB_INVALID_ADDRESS)
        return false;

    lldb::ProcessSP process_sp(options.GetProcessSP());

    if (!process_sp)
        return false;

    const int type_width = sizeof(SourceDataType);
    const int origin_encoding = 8 * type_width ;
    if (origin_encoding != 8 && origin_encoding != 16 && origin_encoding != 32)
        return false;
    // if not UTF8, I need a conversion function to return proper UTF8
    if (origin_encoding != 8 && !ConvertFunction)
        return false;

    if (!options.GetStream())
        return false;

    uint32_t sourceSize = options.GetSourceSize();
    bool needs_zero_terminator = options.GetNeedsZeroTermination();
    
    bool is_truncated = false;
    const auto max_size = process_sp->GetTarget().GetMaximumSizeOfStringSummary();

    if (!sourceSize)
    {
        sourceSize = max_size;
        needs_zero_terminator = true;
    }
    else if (!options.GetIgnoreMaxLength())
    {
        if (sourceSize > max_size)
        {
            sourceSize = max_size;
            is_truncated = true;
        }
    }

    const int bufferSPSize = sourceSize * type_width;

    lldb::DataBufferSP buffer_sp(new DataBufferHeap(bufferSPSize,0));

    if (!buffer_sp->GetBytes())
        return false;

    Error error;
    char *buffer = reinterpret_cast<char *>(buffer_sp->GetBytes());

    if (needs_zero_terminator)
        process_sp->ReadStringFromMemory(options.GetLocation(), buffer, bufferSPSize, error, type_width);
    else
        process_sp->ReadMemoryFromInferior(options.GetLocation(), (char*)buffer_sp->GetBytes(), bufferSPSize, error);

    if (error.Fail())
    {
        options.GetStream()->Printf("unable to read data");
        return true;
    }

    DataExtractor data(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize());
    
    StringPrinter::ReadBufferAndDumpToStreamOptions dump_options(options);
    dump_options.SetData(data);
    dump_options.SetSourceSize(sourceSize);
    dump_options.SetIsTruncated(is_truncated);

    return DumpUTFBufferToStream(ConvertFunction, dump_options);
}

template <>
bool
StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8> (const ReadStringAndDumpToStreamOptions& options)
{
    return ReadUTFBufferAndDumpToStream<UTF8>(options,
                                              nullptr);
}

template <>
bool
StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16> (const ReadStringAndDumpToStreamOptions& options)
{
    return ReadUTFBufferAndDumpToStream<UTF16>(options,
                                               ConvertUTF16toUTF8);
}

template <>
bool
StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF32> (const ReadStringAndDumpToStreamOptions& options)
{
    return ReadUTFBufferAndDumpToStream<UTF32>(options,
                                               ConvertUTF32toUTF8);
}

template <>
bool
StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF8> (const ReadBufferAndDumpToStreamOptions& options)
{
    assert(options.GetStream() && "need a Stream to print the string to");

    return DumpUTFBufferToStream<UTF8>(nullptr, options);
}

template <>
bool
StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::ASCII> (const ReadBufferAndDumpToStreamOptions& options)
{
    // treat ASCII the same as UTF8
    // FIXME: can we optimize ASCII some more?
    return ReadBufferAndDumpToStream<StringElementType::UTF8>(options);
}

template <>
bool
StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF16> (const ReadBufferAndDumpToStreamOptions& options)
{
    assert(options.GetStream() && "need a Stream to print the string to");

    return DumpUTFBufferToStream(ConvertUTF16toUTF8, options);
}

template <>
bool
StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF32> (const ReadBufferAndDumpToStreamOptions& options)
{
    assert(options.GetStream() && "need a Stream to print the string to");

    return DumpUTFBufferToStream(ConvertUTF32toUTF8, options);
}

} // namespace formatters

} // namespace lldb_private
