/*
 * 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 "chunk_reader.h"

#include "compress/compressor_factory.h"
#include "encoding/decoder_factory.h"

using namespace common;
namespace storage {

int ChunkReader::init(ReadFile* read_file, String m_name, TSDataType data_type,
                      Filter* time_filter) {
    read_file_ = read_file;
    measurement_name_.shallow_copy_from(m_name);
    time_decoder_ = DecoderFactory::alloc_time_decoder();
    value_decoder_ = nullptr;
    compressor_ = nullptr;
    time_filter_ = time_filter;
    uncompressed_buf_ = nullptr;
    if (IS_NULL(time_decoder_)) {
        return E_OOM;
    }
    return E_OK;
}

void ChunkReader::reset() {
    chunk_meta_ = nullptr;
    chunk_header_.reset();
    cur_page_header_.reset();

    char* file_data_buf = in_stream_.get_wrapped_buf();
    if (file_data_buf != nullptr) {
        mem_free(file_data_buf);
    }
    in_stream_.reset();
    file_data_buf_size_ = 0;
    chunk_visit_offset_ = 0;
}

void ChunkReader::destroy() {
    if (time_decoder_ != nullptr) {
        time_decoder_->~Decoder();
        DecoderFactory::free(time_decoder_);
        time_decoder_ = nullptr;
    }
    if (value_decoder_ != nullptr) {
        value_decoder_->~Decoder();
        DecoderFactory::free(value_decoder_);
        value_decoder_ = nullptr;
    }
    if (compressor_ != nullptr) {
        compressor_->~Compressor();
        CompressorFactory::free(compressor_);
        compressor_ = nullptr;
    }
    char* buf = in_stream_.get_wrapped_buf();
    if (buf != nullptr) {
        mem_free(buf);
        in_stream_.clear_wrapped_buf();
    }
    cur_page_header_.reset();
    chunk_header_.~ChunkHeader();
}

int ChunkReader::load_by_meta(ChunkMeta* meta) {
    int ret = E_OK;
    chunk_meta_ = meta;
#if DEBUG_SE
    std::cout << "ChunkReader::load_by_meta, meta=" << *meta << std::endl;
#endif
    /* ================ Step 1: reader data from file ================*/
    // at least, we can reader the chunk header and the first page header.
    // TODO configurable
    file_data_buf_size_ = 1024;
    int32_t ret_read_len = 0;
    char* file_data_buf =
        (char*)mem_alloc(file_data_buf_size_, MOD_CHUNK_READER);
    if (IS_NULL(file_data_buf)) {
        return E_OOM;
    }
    ret = read_file_->read(chunk_meta_->offset_of_chunk_header_, file_data_buf,
                           file_data_buf_size_, ret_read_len);
    if (IS_SUCC(ret) && ret_read_len < ChunkHeader::MIN_SERIALIZED_SIZE) {
        ret = E_TSFILE_CORRUPTED;
        LOGE("file corrupted, ret=" << ret << ", offset="
                                    << chunk_meta_->offset_of_chunk_header_
                                    << "read_len=" << ret_read_len);
        mem_free(file_data_buf);
    }

    /* ================ Step 2: deserialize chunk_header ================*/
    if (IS_SUCC(ret)) {
        in_stream_.wrap_from(file_data_buf, ret_read_len);
        // std::cout << "in_stream_.wrap_from " << (void*)file_data_buf <<
        // std::endl;
        if (RET_FAIL(chunk_header_.deserialize_from(in_stream_))) {
        } else if (RET_FAIL(alloc_compressor_and_value_decoder(
                       chunk_header_.encoding_type_, chunk_header_.data_type_,
                       chunk_header_.compression_type_))) {
        } else {
            chunk_visit_offset_ =
                in_stream_.read_pos();  // point to end of chunk_header_
#if DEBUG_SE
            std::cout << "ChunkReader::load_by_meta, chunk_header="
                      << chunk_header_ << std::endl;
#endif
        }
    }
    return ret;
}

int ChunkReader::alloc_compressor_and_value_decoder(
    TSEncoding encoding, TSDataType data_type, CompressionType compression) {
    if (value_decoder_ != nullptr) {
        value_decoder_->reset();
    } else {
        value_decoder_ =
            DecoderFactory::alloc_value_decoder(encoding, data_type);
        if (IS_NULL(value_decoder_)) {
            return E_OOM;
        }
    }

    if (compressor_ != nullptr) {
        compressor_->reset(/*for_compress*/ false);
    } else {
        compressor_ = CompressorFactory::alloc_compressor(compression);
        if (compressor_ == nullptr) {
            return E_OOM;
        }
    }
    return E_OK;
}

int ChunkReader::get_next_page(TsBlock* ret_tsblock, Filter* oneshoot_filter,
                               PageArena& pa) {
    int ret = E_OK;
    Filter* filter =
        (oneshoot_filter != nullptr ? oneshoot_filter : time_filter_);

    if (prev_page_not_finish()) {
        ret = decode_tv_buf_into_tsblock_by_datatype(time_in_, value_in_,
                                                     ret_tsblock, filter, &pa);
        if (ret == E_OVERFLOW) {
            ret = E_OK;
        } else {
            if (uncompressed_buf_ != nullptr) {
                compressor_->after_uncompress(uncompressed_buf_);
                uncompressed_buf_ = nullptr;
            }
            time_in_.reset();
            value_in_.reset();
        }
        return ret;
    }

    while (IS_SUCC(ret)) {
        if (!has_more_data()) {
            return E_NO_MORE_DATA;
        }
        if (RET_FAIL(get_cur_page_header())) {
        } else if (cur_page_statisify_filter(filter)) {
            break;
        } else if (RET_FAIL(skip_cur_page())) {
        }
    }

    if (IS_SUCC(ret)) {
        ret = decode_cur_page_data(ret_tsblock, filter, pa);
    }
    return ret;
}

int ChunkReader::get_cur_page_header() {
    int ret = E_OK;
    bool retry = true;
    int cur_page_header_serialized_size = 0;
    do {
        in_stream_.mark_read_pos();
        cur_page_header_.reset();
        ret = cur_page_header_.deserialize_from(
            in_stream_, !chunk_has_only_one_page(), chunk_header_.data_type_);
        cur_page_header_serialized_size = in_stream_.get_mark_len();
        if (deserialize_buf_not_enough(ret) && retry) {
            retry = false;
            ret = read_from_file_and_rewrap();
            if (E_OK == ret) {
                continue;
            }
        }
        break;
    } while (true);
    if (IS_SUCC(ret)) {
        // visit a header
        chunk_visit_offset_ += cur_page_header_serialized_size;
    }
#if DEBUG_SE
    std::cout << "get_cur_page_header, ret=" << ret << ", retry=" << retry
              << ", cur_page_header_=" << cur_page_header_
              << ", chunk_meta_->offset_of_chunk_header_="
              << chunk_meta_->offset_of_chunk_header_
              << ", cur_page_header_serialized_size="
              << cur_page_header_serialized_size << std::endl;
#endif
    return ret;
}

// reader at least @want_size bytes from file and wrap the buffer into
// @in_stream_
int ChunkReader::read_from_file_and_rewrap(int want_size) {
    int ret = E_OK;
    const int DEFAULT_READ_SIZE = 4096;  // may use page_size + page_header_size
    char* file_data_buf = in_stream_.get_wrapped_buf();
    int offset = chunk_meta_->offset_of_chunk_header_ + chunk_visit_offset_;
    int read_size =
        (want_size < DEFAULT_READ_SIZE ? DEFAULT_READ_SIZE : want_size);
    if (file_data_buf_size_ < read_size ||
        read_size < file_data_buf_size_ / 10) {
        file_data_buf = (char*)mem_realloc(file_data_buf, read_size);
        if (IS_NULL(file_data_buf)) {
            return E_OOM;
        }
        file_data_buf_size_ = read_size;
    }
    int ret_read_len = 0;
    if (RET_FAIL(
            read_file_->read(offset, file_data_buf, read_size, ret_read_len))) {
    } else {
        in_stream_.wrap_from(file_data_buf, ret_read_len);
        // DEBUG_hex_dump_buf("wrapped buf = ", file_data_buf, 256);
    }
    return ret;
}

bool ChunkReader::cur_page_statisify_filter(Filter* filter) {
    return filter == nullptr || cur_page_header_.statistic_ == nullptr ||
           filter->satisfy(cur_page_header_.statistic_);
}

int ChunkReader::skip_cur_page() {
    int ret = E_OK;
    // visit a page tv data
    chunk_visit_offset_ += cur_page_header_.compressed_size_;
    in_stream_.wrapped_buf_advance_read_pos(cur_page_header_.compressed_size_);
    return ret;
}

int ChunkReader::decode_cur_page_data(TsBlock*& ret_tsblock, Filter* filter,
                                      PageArena& pa) {
    int ret = E_OK;

    // Step 1: make sure we load the whole page data in @in_stream_
    if (in_stream_.remaining_size() < cur_page_header_.compressed_size_) {
        // std::cout << "decode_cur_page_data. in_stream_.remaining_size="<<
        // in_stream_.remaining_size() << ", cur_page_header_.compressed_size_="
        // << cur_page_header_.compressed_size_ << std::endl;
        if (RET_FAIL(
                read_from_file_and_rewrap(cur_page_header_.compressed_size_))) {
        }
    }

    char* compressed_buf = nullptr;
    char* uncompressed_buf = nullptr;
    uint32_t compressed_buf_size = 0;  // cppcheck-suppress unreadVariable
    uint32_t uncompressed_buf_size = 0;
    char* time_buf = nullptr;
    char* value_buf = nullptr;
    uint32_t time_buf_size = 0;
    uint32_t value_buf_size = 0;

    // Step 2: do uncompress
    if (IS_SUCC(ret)) {
        compressed_buf = in_stream_.get_wrapped_buf() + in_stream_.read_pos();
        // std::cout << "ChunkReader::decode_cur_page_data,
        // in_stream_.get_wrapped_buf="
        // <<(void*)(in_stream_.get_wrapped_buf())<< ", in_stream_.read_pos=" <<
        // in_stream_.read_pos() << std::endl;
        compressed_buf_size = cur_page_header_.compressed_size_;
        in_stream_.wrapped_buf_advance_read_pos(compressed_buf_size);
        chunk_visit_offset_ += compressed_buf_size;
        if (RET_FAIL(compressor_->reset(false))) {
        } else if (RET_FAIL(compressor_->uncompress(
                       compressed_buf, compressed_buf_size, uncompressed_buf,
                       uncompressed_buf_size))) {
        } else {
            uncompressed_buf_ = uncompressed_buf;
        }
        // DEBUG_hex_dump_buf("ChunkReader reader, uncompressed buf = ",
        // uncompressed_buf, uncompressed_buf_size);
        if (ret != E_OK ||
            uncompressed_buf_size != cur_page_header_.uncompressed_size_) {
            ret = E_TSFILE_CORRUPTED;
            ASSERT(false);
        }
    }

    // Step 3: get time_buf & value_buf
    if (IS_SUCC(ret)) {
        int var_size = 0;
        if (RET_FAIL(SerializationUtil::read_var_uint(
                time_buf_size, uncompressed_buf, uncompressed_buf_size,
                &var_size))) {
        } else {
            time_buf = uncompressed_buf + var_size;
            value_buf = time_buf + time_buf_size;
            value_buf_size = uncompressed_buf_size - var_size - time_buf_size;
#if DEBUG_SE
            std::cout << "ChunkReader uncompress: compressed_buf_size="
                      << compressed_buf_size
                      << ", uncompressed_buf_size=" << uncompressed_buf_size
                      << ", var_size=" << var_size
                      << ", time_buf_size=" << time_buf_size << std::endl;
#endif
            if (uncompressed_buf_size <= var_size + time_buf_size) {
                ret = E_TSFILE_CORRUPTED;
                ASSERT(false);
            }
        }
    }

    // Step 4: decode time-value buffer into @ret_tsblock
    if (IS_SUCC(ret)) {
        time_decoder_->reset();
        value_decoder_->reset();
        time_in_.wrap_from(time_buf, time_buf_size);
        value_in_.wrap_from(value_buf, value_buf_size);
        // ret = decode_tv_buf_into_tsblock(time_buf, value_buf, time_buf_size,
        //                                  value_buf_size, ret_tsblock,
        //                                  filter);
        ret = decode_tv_buf_into_tsblock_by_datatype(time_in_, value_in_,
                                                     ret_tsblock, filter, &pa);
        // if we return during @decode_tv_buf_into_tsblock, we should keep
        // @uncompressed_buf_ valid until all TV pairs are decoded.
        if (ret != E_OVERFLOW) {
            if (uncompressed_buf_ != nullptr) {
                compressor_->after_uncompress(uncompressed_buf_);
                uncompressed_buf_ = nullptr;
            }
            time_in_.reset();
            value_in_.reset();
        } else {
            ret = E_OK;
        }
    }
    return ret;
}

#define DECODE_TYPED_TV_INTO_TSBLOCK(CppType, ReadType, time_in, value_in,     \
                                     row_appender)                             \
    do {                                                                       \
        int64_t time = 0;                                                      \
        CppType value;                                                         \
        while (time_decoder_->has_remaining(time_in)) {                        \
            ASSERT(value_decoder_->has_remaining(value_in));                   \
            if (UNLIKELY(!row_appender.add_row())) {                           \
                ret = E_OVERFLOW;                                              \
                break;                                                         \
            } else if (RET_FAIL(time_decoder_->read_int64(time, time_in))) {   \
            } else if (RET_FAIL(value_decoder_->read_##ReadType(value,         \
                                                                value_in))) {  \
            } else if (filter != nullptr && !filter->satisfy(time, value)) {   \
                row_appender.backoff_add_row();                                \
                continue;                                                      \
            } else {                                                           \
                /*std::cout << "decoder: time=" << time << ", value=" << value \
                 * << std::endl;*/                                             \
                row_appender.append(0, (char*)&time, sizeof(time));            \
                row_appender.append(1, (char*)&value, sizeof(value));          \
            }                                                                  \
        }                                                                      \
    } while (false)

int ChunkReader::i32_DECODE_TYPED_TV_INTO_TSBLOCK(ByteStream& time_in,
                                                  ByteStream& value_in,
                                                  RowAppender& row_appender,
                                                  Filter* filter) {
    int ret = E_OK;
    do {
        int64_t time = 0;
        int32_t value;
        while (time_decoder_->has_remaining(time_in)) {
            ASSERT(value_decoder_->has_remaining(value_in));
            if (UNLIKELY(!row_appender.add_row())) {
                ret = E_OVERFLOW;
                break;
            } else if (RET_FAIL(time_decoder_->read_int64(time, time_in))) {
            } else if (RET_FAIL(value_decoder_->read_int32(value, value_in))) {
            } else if (filter != nullptr && !filter->satisfy(time, value)) {
                row_appender.backoff_add_row();
                continue;
            } else {
                /*std::cout << "decoder: time=" << time << ", value=" << value
                 * << std::endl;*/
                row_appender.append(0, (char*)&time, sizeof(time));
                row_appender.append(1, (char*)&value, sizeof(value));
            }
        }
    } while (false);
    return ret;
}

int ChunkReader::STRING_DECODE_TYPED_TV_INTO_TSBLOCK(ByteStream& time_in,
                                                     ByteStream& value_in,
                                                     RowAppender& row_appender,
                                                     PageArena& pa,
                                                     Filter* filter) {
    int ret = E_OK;
    int64_t time = 0;
    common::String value;
    while (time_decoder_->has_remaining(time_in)) {
        ASSERT(value_decoder_->has_remaining(value_in));
        if (UNLIKELY(!row_appender.add_row())) {
            ret = E_OVERFLOW;
            break;
        } else if (RET_FAIL(time_decoder_->read_int64(time, time_in))) {
        } else if (RET_FAIL(value_decoder_->read_String(value, pa, value_in))) {
        } else if (filter != nullptr && !filter->satisfy(time, value)) {
            row_appender.backoff_add_row();
            continue;
        } else {
            row_appender.append(0, (char*)&time, sizeof(time));
            row_appender.append(1, value.buf_, value.len_);
        }
    }
    return ret;
}

int ChunkReader::decode_tv_buf_into_tsblock_by_datatype(ByteStream& time_in,
                                                        ByteStream& value_in,
                                                        TsBlock* ret_tsblock,
                                                        Filter* filter,
                                                        common::PageArena* pa) {
    int ret = E_OK;
    RowAppender row_appender(ret_tsblock);
    switch (chunk_header_.data_type_) {
        case common::BOOLEAN:
            DECODE_TYPED_TV_INTO_TSBLOCK(bool, boolean, time_in_, value_in_,
                                         row_appender);
            break;
        case common::DATE:
        case common::INT32:
            // DECODE_TYPED_TV_INTO_TSBLOCK(int32_t, int32, time_in_, value_in_,
            // row_appender);
            ret = i32_DECODE_TYPED_TV_INTO_TSBLOCK(time_in_, value_in_,
                                                   row_appender, filter);
            break;
        case TIMESTAMP:
        case common::INT64:
            DECODE_TYPED_TV_INTO_TSBLOCK(int64_t, int64, time_in_, value_in_,
                                         row_appender);
            break;
        case common::FLOAT:
            DECODE_TYPED_TV_INTO_TSBLOCK(float, float, time_in_, value_in_,
                                         row_appender);
            break;
        case common::DOUBLE:
            DECODE_TYPED_TV_INTO_TSBLOCK(double, double, time_in_, value_in_,
                                         row_appender);
            break;
        case common::TEXT:
        case common::BLOB:
        case common::STRING:
            ret = STRING_DECODE_TYPED_TV_INTO_TSBLOCK(
                time_in, value_in, row_appender, *pa, filter);
            break;
        default:
            ret = E_NOT_SUPPORT;
            ASSERT(false);
    }
    if (ret_tsblock->get_row_count() == 0 && ret == E_OK) {
        ret = E_NO_MORE_DATA;
    }
    return ret;
}

}  // end namespace storage