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

using namespace common;

namespace storage {

int DataRun::remove_tsfile(const FileID &to_remove) {
    ASSERT(run_type_ == DRT_TSFILE);
    int ret = E_OK;

    SimpleList<OpenFile *>::Iterator it = tsfile_list_.begin();
    OpenFile *of = nullptr;
    for (; it != tsfile_list_.end(); it++) {
        OpenFile *cur = it.get();
        if (cur->get_file_id() == to_remove) {
            of = cur;
            break;
        }
    }
    if (of != nullptr) {
        ret = tsfile_list_.remove(of);
    }
    return ret;
}

int DataRun::get_next(TsBlock *ret_block, TimeRange &ret_time_range,
                      bool alloc_tsblock) {
    if (run_type_ == DRT_TVLIST) {
        return tvlist_get_next(ret_block, ret_time_range, alloc_tsblock);
    } else {
        ASSERT(run_type_ == DRT_TSFILE);
        return tsfile_get_next(ret_block, ret_time_range, alloc_tsblock);
    }
}

TsBlock *DataRun::alloc_tsblock() {
    tuple_desc_.reset();
    // TODO default config of time_cd
    tuple_desc_.push_back(g_time_column_schema);
    tuple_desc_.push_back(*col_schema_);
    return (new TsBlock(&tuple_desc_));
}

int DataRun::tvlist_get_next(TsBlock *ret_block, TimeRange &ret_time_range,
                             bool tsblock) {
    // TODO @tsblock
    int ret = E_OK;
    if (UNLIKELY(!tvlist_list_iter_.is_inited())) {
        tvlist_list_iter_ = tvlist_list_.begin();
    }

    while (true) {
        if (tvlist_list_iter_ == tvlist_list_.end()) {
            return E_NO_MORE_DATA;
        } else {
            SeqTVListBase *tvlist_base = tvlist_list_iter_.get();
            if (!tvlist_base->is_immutable()) {
                tvlist_base->lock();
            }
            ret = fill_tsblock_from_tvlist(tvlist_base, ret_block,
                                           ret_time_range);
            if (ret == E_NO_MORE_DATA) {
                ret = E_OK;
            }
            if (!tvlist_base->is_immutable()) {
                tvlist_base->unlock();
            }
            tvlist_list_iter_++;
            return ret;
        }
    }
    return ret;
}

int DataRun::fill_tsblock_from_tvlist(SeqTVListBase *tvlist, TsBlock *ret_block,
                                      TimeRange &ret_time_range) {
    int ret = E_OK;
    switch (col_schema_->data_type_) {
        case common::BOOLEAN:
            ret = fill_tsblock_from_typed_tvlist<bool>(tvlist, ret_block,
                                                       ret_time_range);
            break;
        case common::INT32:
            ret = fill_tsblock_from_typed_tvlist<int32_t>(tvlist, ret_block,
                                                          ret_time_range);
            break;
        case common::INT64:
            ret = fill_tsblock_from_typed_tvlist<int64_t>(tvlist, ret_block,
                                                          ret_time_range);
            break;
        case common::FLOAT:
            ret = fill_tsblock_from_typed_tvlist<float>(tvlist, ret_block,
                                                        ret_time_range);
            break;
        case common::DOUBLE:
            ret = fill_tsblock_from_typed_tvlist<double>(tvlist, ret_block,
                                                         ret_time_range);
            break;
        default:
            ASSERT(false);
            break;
    }
    return ret;
}

template <typename T>
int DataRun::fill_tsblock_from_typed_tvlist(SeqTVListBase *tvlist,
                                            TsBlock *ret_block,
                                            TimeRange &ret_time_range) {
    int ret = E_OK;

    SeqTVList<T> *typed_tvlist = static_cast<SeqTVList<T> *>(tvlist);
    typename SeqTVList<T>::Iterator it;
    it = typed_tvlist->scan_without_lock();
    typename SeqTVList<T>::TV tv;

    // FIXME do not append all tvlist data into tsblock in one time.
    ret_time_range.start_time_ = typed_tvlist->time_at(0);
    RowAppender row_appender(ret_block);
#ifndef NDEBUG
    int count = 0;
#endif
    while (E_OK == (ret = it.next(tv))) {
        ret_time_range.end_time_ = tv.time_;
#ifndef NDEBUG
        std::cout << "DataRun::fill_tsblock_from_typed_tvlist: [" << count
                  << "] = <" << tv.time_ << ", " << tv.value_ << ">"
                  << std::endl;
#endif
        row_appender.add_row();
        row_appender.append(0, reinterpret_cast<char *>(&tv.time_),
                            sizeof(tv.time_));
        row_appender.append(1, reinterpret_cast<char *>(&tv.value_),
                            sizeof(tv.value_));
    }
    return ret;
}

int DataRun::reinit_io_reader(SimpleList<OpenFile *>::Iterator &it,
                              common::PageArena *pa) {
    int ret = E_OK;
    // maybe io_reader_ destroy before re-init
    OpenFile *open_file = it.get();
    io_reader_.reset();
    if (RET_FAIL(io_reader_.init(open_file->get_file_path()))) {
        ////log_err("io_reader init error, ret=%d, file_path=%s",
        // ret, open_file->get_file_path().c_str());
    } else {
        std::shared_ptr<IDeviceID> device_id = std::make_shared<StringArrayDeviceID>(col_schema_->get_device_name_str());
        std::string measurement_name = col_schema_->get_measurement_name_str();
        if (ssi_ != nullptr) {
            delete ssi_;
            ssi_ = nullptr;
        }
        if (RET_FAIL(io_reader_.alloc_ssi(device_id, measurement_name, ssi_,
                                          *pa))) {
        }
    }
    return ret;
}

int DataRun::tsfile_get_next(TsBlock *ret_tsblock, TimeRange &ret_time_range,
                             bool alloc_tsblock) {
    int ret = E_OK;
    if (UNLIKELY(!tsfile_list_iter_.is_inited())) {
        tsfile_list_iter_ = tsfile_list_.begin();
        if (tsfile_list_iter_ == tsfile_list_.end()) {  // all file iterated
            ret = E_NO_MORE_DATA;
        } else if (RET_FAIL(reinit_io_reader(tsfile_list_iter_))) {
        }
    }

    if (IS_SUCC(ret)) {
        // ret = io_reader_.get_next(*col_desc_, ret_tsblock, ret_time_range);
        ret = ssi_->get_next(ret_tsblock, alloc_tsblock);
        if (E_NO_MORE_DATA == ret) {  // current file reach end
            tsfile_list_iter_++;
            if (tsfile_list_iter_ == tsfile_list_.end()) {  // all file iterated
                ret = E_NO_MORE_DATA;
            } else if (RET_FAIL(reinit_io_reader(tsfile_list_iter_))) {
            }
        }
    }
    return ret;
}

DataRun *DataScanIterator::alloc_data_run(DataRunType run_type) {
    void *buf = page_arena_.alloc(sizeof(DataRun));
    if (IS_NULL(buf)) {
        return nullptr;
    }
    return (new (buf) DataRun(run_type, &col_schema_, &page_arena_));
}

#ifndef NDEBUG
void DataScanIterator::DEBUG_dump_data_run_list() {
    SimpleList<DataRun *>::Iterator it;
    std::cout << "\n/---- DEBUG_dump_data_run_list: size="
              << data_run_list_.size() << "----\\" << std::endl;
    int idx = 0;
    for (it = data_run_list_.begin(); it != data_run_list_.end(); it++) {
        std::cout << "[" << (idx++) << "]" << *it.get() << std::endl;
    }
    std::cout << "\\---- DEBUG_dump_data_run_list: size="
              << data_run_list_.size() << "----/\n"
              << std::endl;
}
#endif

int DataScanIterator::get_next(TsBlock *ret_block, bool alloc_tsblock) {
#ifndef NDEBUG
    DEBUG_dump_data_run_list();
#endif
    int ret = E_OK;

    if (UNLIKELY(!cursor_.is_inited())) {
        cursor_ = data_run_list_.begin();
    }

    while (true) {
        TimeRange time_range;
        DataRun *data_run = cursor_.get();
        ret = data_run->get_next(ret_block, time_range, alloc_tsblock);
        if (ret == E_OK) {
            return ret;
        } else if (ret == E_NO_MORE_DATA) {
            cursor_++;
            if (cursor_ == data_run_list_.end()) {
                return E_NO_MORE_DATA;
            }
        } else {
            // log_err("data run get next batch error, ret=%d", ret);
            break;
        }
    }
    return ret;
}

}  // end namespace storage