// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

// Date: Thu Nov 22 13:57:56 CST 2012

#include <inttypes.h>
#include "butil/iobuf.h"
#include "butil/binary_printer.h"

namespace butil {

static char s_binary_char_map[] = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    'A', 'B', 'C', 'D', 'E', 'F'
};

template <typename Appender>
class BinaryCharPrinter {
public:
    static const size_t BUF_SIZE = 127;
    explicit BinaryCharPrinter(Appender* a) : _n(0), _appender(a) {}
    ~BinaryCharPrinter() { Flush(); }
    void PushChar(unsigned char c);
    void Flush();
private:
    uint32_t _n;
    Appender* _appender;
    char _buf[BUF_SIZE];
};

template <typename Appender>
void BinaryCharPrinter<Appender>::Flush() {
    if (_n > 0) {
        _appender->Append(_buf, _n);
        _n = 0;
    }
}

template <typename Appender>
void BinaryCharPrinter<Appender>::PushChar(unsigned char c) {
    if (_n > BUF_SIZE - 3) {
        _appender->Append(_buf, _n);
        _n = 0;
    }
    if (c >= 32 && c <= 126) { // displayable ascii characters
        if (c != '\\') {
            _buf[_n++] = c;
        } else {
            _buf[_n++] = '\\';
            _buf[_n++] = '\\';
        }
    } else {
        _buf[_n++] = '\\';
        switch (c) {
        case '\b': _buf[_n++] = 'b'; break;
        case '\t': _buf[_n++] = 't'; break;
        case '\n': _buf[_n++] = 'n'; break;
        case '\r': _buf[_n++] = 'r'; break;
        default: 
            _buf[_n++] = s_binary_char_map[c >> 4];
            _buf[_n++] = s_binary_char_map[c & 0xF];
            break;
        }
    }
}

class OStreamAppender {
public:
    OStreamAppender(std::ostream& os) : _os(&os) {}
    void Append(const char* b, size_t n) { _os->write(b, n); }
private:
    std::ostream* _os;
};

class StringAppender {
public:
    StringAppender(std::string* str) : _str(str) {}
    void Append(const char* b, size_t n) { _str->append(b, n); }
private:
    std::string* _str;
};

template <typename Appender>
static void PrintIOBuf(Appender* appender, const IOBuf& b, size_t max_length) {
    BinaryCharPrinter<Appender> printer(appender);
    const size_t n = b.backing_block_num();
    size_t nw = 0;
    for (size_t i = 0; i < n; ++i) {
        StringPiece blk = b.backing_block(i);
        for (size_t j = 0; j < blk.size(); ++j) {
            if (nw >= max_length) {
                printer.Flush();
                char buf[48];
                int len = snprintf(buf, sizeof(buf), "...<skipping %" PRIu64 " bytes>",
                        (uint64_t)(b.size() - nw));
                appender->Append(buf, len);
                return;
            }
            ++nw;
            printer.PushChar(blk[j]);
        }
    }
}

template <typename Appender>
static void PrintString(Appender* appender, const StringPiece& s, size_t max_length) {
    BinaryCharPrinter<Appender> printer(appender);
    for (size_t i = 0; i < s.size(); ++i) {
        if (i >= max_length) {
            printer.Flush();
            char buf[48];
            int len = snprintf(buf, sizeof(buf), "...<skipping %" PRIu64 " bytes>",
                               (uint64_t)(s.size() - i));
            appender->Append(buf, len);
            return;
        }
        printer.PushChar(s[i]);
    }
}

void ToPrintable::Print(std::ostream& os) const {
    OStreamAppender appender(os);
    if (_iobuf) {
        PrintIOBuf(&appender, *_iobuf, _max_length);
    } else if (!_str.empty()) {
        PrintString(&appender, _str, _max_length);
    }
}

std::string ToPrintableString(const IOBuf& data, size_t max_length) {
    std::string result;
    StringAppender appender(&result);
    PrintIOBuf(&appender, data, max_length);
    return result;
}

std::string ToPrintableString(const StringPiece& data, size_t max_length) {
    std::string result;
    StringAppender appender(&result);
    PrintString(&appender, data, max_length);
    return result;
}

std::string ToPrintableString(const void* data, size_t n, size_t max_length) {
    std::string result;
    StringAppender appender(&result);
    PrintString(&appender, StringPiece((const char*)data, n), max_length);
    return result;
}

} // namespace butil
