/*
 * 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.
 */
#include "tsblock.h"

#include <cstring>
#include <string>

namespace common {

int TsBlock::init() {
    // todo: The current version select_list_ is useless, so it is not
    // initialized
    int ret = 0;
    uint32_t row_size = tuple_desc_->get_single_row_len(&ret);
    if (ret != 0) {
        return ret;
    }

    // No maximum number of rows given, calculated with capacity_
    if (LIKELY(max_row_count_ == 0)) {
        max_row_count_ = capacity_ / row_size;
    } else {
        // max_row_count_ given, calculated with max_row_count_
        capacity_ = row_size * max_row_count_;
    }
    int colnum = tuple_desc_->get_column_count();
    for (int i = 0; i < colnum; ++i) {
        ret = build_vector(tuple_desc_->get_column_type(i), max_row_count_);
        if (ret != 0) {
            return ret;
        }
    }
    return ret;
}

int TsBlock::build_vector(common::TSDataType type, uint32_t row_count) {
    Vector* vec;
    int ret = 0;
    if (LIKELY(type != common::TEXT && type != common::STRING &&
               type != common::BLOB)) {
        vec = new FixedLengthVector(type, row_count, get_len(type), this);
    } else if (type == common::TEXT || type == common::STRING ||
               type == common::BLOB) {
        vec = new VariableLengthVector(
            type, row_count, DEFAULT_RESERVED_SIZE_OF_TEXT + TEXT_LEN, this);
    } else {
        // log_err("TsBlock::BuildVector failed because of unknown type %d",
        // static_cast<int>(type));
        ret = E_TYPE_NOT_SUPPORTED;
    }
    vectors_.push_back(vec);
    return ret;
}

void TsBlock::write_data(ByteStream* __restrict byte_stream,
                         char* __restrict val, uint32_t len, bool has_null,
                         TSDataType type) {
    std::string strval;
    switch (type) {
        case common::INT64: {
            int64_t ival;
            std::memcpy(&ival, val, sizeof(ival));
            strval = std::to_string(ival);
            break;
        }
        case common::INT32: {
            int32_t ival;
            std::memcpy(&ival, val, sizeof(ival));
            strval = std::to_string(ival);
            break;
        }
        case common::FLOAT: {
            float ival;
            std::memcpy(&ival, val, sizeof(ival));
            strval = std::to_string(ival);
            break;
        }
        case common::DOUBLE: {
            double ival;
            std::memcpy(&ival, val, sizeof(ival));
            strval = std::to_string(ival);
            break;
        }
        case common::BOOLEAN: {
            bool ival;
            std::memcpy(&ival, val, sizeof(ival));
            if (ival) {
                strval = "true";
            } else {
                strval = "false";
            }
            break;
        }
        case common::TEXT: {
            if (LIKELY(!has_null)) {
                byte_stream->write_buf(val, len);
            } else {
                byte_stream->write_buf("null", 4);
            }
            byte_stream->write_buf(",\n", 2);
            return;
        }
        default: {
            // log_err("write_data unknown type");
        }
    }
    if (LIKELY(!has_null)) {
        byte_stream->write_buf(const_cast<char*>(strval.c_str()),
                               strval.length());
    } else {
        byte_stream->write_buf("null", 4);
    }
}

void TsBlock::tsblock_to_json(ByteStream* byte_stream) {
    // 1. append start tag
    byte_stream->write_buf("{\n", 2);

    // 2. append output columns to bytestream
    int column_count = tuple_desc_->get_column_count();
    // 2.1 append header
    byte_stream->write_buf("  \"expressions\": [\n", 19);
    // 2.2 append column names
    for (int i = 1; i < column_count; ++i) {
        std::string name = tuple_desc_->get_column_name(i);
        byte_stream->write_buf("    ", 4);
        byte_stream->write_buf("\"", 1);
        byte_stream->write_buf(name.c_str(), name.length());
        byte_stream->write_buf("\"", 1);
        if (i == column_count - 1) {
            byte_stream->write_buf("\n", 1);
        } else {
            byte_stream->write_buf(",\n", 2);
        }
    }
    byte_stream->write_buf("  ],\n", 5);

    // 3. append column_names
    byte_stream->write_buf("  \"column_names\": null,\n", 24);

    // 4. append time value
    byte_stream->write_buf("  \"timestamps\": [\n", 18);
    ColIterator time_iter(0, this);
    bool is_first = true;
    while (!time_iter.end()) {
        uint32_t ilen;
        byte_stream->write_buf("    ", 4);
        char* val = time_iter.read(&ilen);
        if (!is_first) {
            byte_stream->write_buf(",\n", 2);
        }
        is_first = false;
        write_data(byte_stream, val, ilen, false, INT64);
        time_iter.next();
    }
    byte_stream->write_buf("  ],\n", 5);

    // 5. append user values
    byte_stream->write_buf("  \"values\": [\n", 14);
    for (int i = 1; i < column_count; ++i) {
        byte_stream->write_buf("    [\n", 6);

        ColIterator value_iter(i, this);
        bool has_null = value_iter.has_null();
        if (LIKELY(!has_null)) {
            bool is_first = true;  // cppcheck-suppress shadowVariable
            while (!value_iter.end()) {
                uint32_t ilen = 0;
                byte_stream->write_buf("      ", 6);
                char* val = value_iter.read(&ilen);
                if (!is_first) {
                    byte_stream->write_buf(",\n", 2);
                }
                is_first = false;
                write_data(byte_stream, val, ilen, false,
                           tuple_desc_->get_column_type(i));
                value_iter.next();
            }
        } else {
            while (!value_iter.end()) {
                bool inull;
                uint32_t ilen = 0;
                byte_stream->write_buf("      ", 6);
                char* val = value_iter.read(&ilen, &inull);
                if (!is_first) {
                    byte_stream->write_buf(",\n", 2);
                }
                is_first = false;
                write_data(byte_stream, val, ilen, inull,
                           tuple_desc_->get_column_type(i));
                value_iter.next();
            }
        }
        if (i == column_count - 1) {
            byte_stream->write_buf("    ]\n", 6);
        } else {
            byte_stream->write_buf("    ],\n", 7);
        }
    }
    byte_stream->write_buf("  ]\n", 4);

    // 6. end
    byte_stream->write_buf("}\n", 2);
}

#ifdef DEBUG
std::string TsBlock::debug_string() {
    std::stringstream out;
    out << "print TsBlock: " << this << std::endl
        << "capacity_: " << capacity_ << std::endl
        << "row_count_: " << row_count_ << std::endl
        << "max_row_count_: " << max_row_count_ << std::endl;

    out << "------ tuple desc ------" << std::endl << std::endl;
    out << tuple_desc_->debug_string() << std::endl;

    out << "------ real data area ------" << std::endl;

    RowIterator iter(this);
    while (!iter.end()) {
        out << iter.debug_string() << std::endl;
        iter.next();
    }
    return out.str();
}

std::string RowIterator::debug_string() {
    std::stringstream out;
    out.precision(20);  // Default precision is 6, set precision, otherwise
                        // double precision will be lost

    for (uint32_t i = 0; i < column_count_; ++i) {
        bool is_null = false;
        uint32_t len = 0;
        void* value = read(i, &len, &is_null);
        if (is_null) {
            out << "NULL";
        } else {
            ColumnSchema& col_schema =
                tsblock_->tuple_desc_->get_column_schema(i);
            switch (col_schema.data_type_) {
                case common::BOOLEAN: {
                    out << *static_cast<bool*>(value);
                    break;
                }
                case common::INT32: {
                    out << *static_cast<int32_t*>(value);
                    break;
                }
                case common::INT64: {
                    out << *static_cast<int64_t*>(value);
                    break;
                }
                case common::FLOAT: {
                    out << *static_cast<float*>(value);
                    break;
                }
                case common::DOUBLE: {
                    out << *static_cast<double*>(value);
                    break;
                }
                case common::TEXT: {
                    out << std::string(static_cast<char*>(value), len);
                    break;
                }
                case common::STRING: {
                    out << *static_cast<String*>(value);
                    break;
                }
                default: {
                    out << "ERR";
                }
            }
        }
        if (i + 1 < tsblock_->tuple_desc_->get_column_count()) {
            out << ", ";
        }
    }
    return out.str();
}
#endif
// TODO use memcpy in vector instead of using iter/appender
int merge_tsblock_by_row(TsBlock* sea, TsBlock* river) {
    int ret = E_OK;
    TupleDesc* sea_tuple_desc = sea->get_tuple_desc();
    TupleDesc* river_tupe_desc = river->get_tuple_desc();
    if (!sea_tuple_desc->equal_to(*river_tupe_desc)) {
        ret = E_NOT_MATCH;
    } else {
        RowAppender sea_appender(sea);
        RowIterator river_iter(river);
        while (!river_iter.end()) {
            sea_appender.add_row();
            for (uint32_t c = 0; c < sea_tuple_desc->get_column_count(); c++) {
                uint32_t len = 0;
                bool null = false;
                char* val = river_iter.read(c, &len, &null);
                sea_appender.append(c, val, len);
            }
            river_iter.next();
        }
    }
    return ret;
}

}  // namespace common
