// 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 "meta-service/table_stream_metadata_reader.h"

#include <fmt/format.h>

#include <optional>
#include <utility>

#include "common/logging.h"
#include "meta-service/meta_service_helper.h"
#include "meta-store/clone_chain_reader.h"
#include "meta-store/keys.h"
#include "meta-store/txn_kv.h"
#include "meta-store/txn_kv_error.h"

namespace doris::cloud {
namespace {

TableStreamReadResult read_error(TxnErrorCode err, std::string_view object) {
    const MetaServiceCode code = err == TxnErrorCode::TXN_INVALID_DATA
                                         ? MetaServiceCode::PROTOBUF_PARSE_ERR
                                         : cast_as<ErrCategory::READ>(err);
    return {code, fmt::format("failed to read {}, err={}", object, err)};
}

std::vector<int64_t> collect_partition_ids(const std::vector<TableStreamPartitionSetPB>& bindings) {
    std::vector<int64_t> partition_ids;
    std::unordered_set<int64_t> seen_partition_ids;
    for (const TableStreamPartitionSetPB& binding : bindings) {
        for (int64_t partition_id : binding.partition_ids()) {
            if (seen_partition_ids.insert(partition_id).second) {
                partition_ids.push_back(partition_id);
            }
        }
    }
    return partition_ids;
}

} // namespace

bool is_valid_table_stream_identity(const TableStreamIdentityPB& identity) {
    return identity.has_base_db_id() && identity.base_db_id() > 0 && identity.has_base_table_id() &&
           identity.base_table_id() > 0 && identity.has_stream_db_id() &&
           identity.stream_db_id() > 0 && identity.has_stream_id() && identity.stream_id() > 0;
}

bool is_valid_table_stream_offset_tso(int64_t offset_tso) {
    return offset_tso == -1 || offset_tso > 0;
}

TableStreamReadResult read_table_stream_multi_version_status(
        Transaction* txn, std::string_view instance_id, TableStreamReadIntent intent,
        MultiVersionStatus* multi_version_status) {
    std::string value;
    TxnErrorCode err = txn->get(instance_key({std::string(instance_id)}), &value,
                                intent == TableStreamReadIntent::SNAPSHOT);
    if (err != TxnErrorCode::TXN_OK) {
        return read_error(err, "instance metadata for Table Stream");
    }

    InstanceInfoPB instance;
    if (!instance.ParseFromString(value)) {
        return {MetaServiceCode::PROTOBUF_PARSE_ERR,
                "malformed instance metadata for Table Stream"};
    }
    *multi_version_status = instance.multi_version_status();
    if (*multi_version_status == MultiVersionStatus::MULTI_VERSION_ENABLED) {
        return {MetaServiceCode::INVALID_ARGUMENT,
                "Table Stream is not supported in MULTI_VERSION_ENABLED mode"};
    }
    return {};
}

TableStreamMetadataReader::TableStreamMetadataReader(Transaction* txn, std::string_view instance_id,
                                                     MultiVersionStatus multi_version_status,
                                                     CloneChainReader* clone_chain_reader)
        : txn_(txn),
          instance_id_(instance_id),
          multi_version_status_(multi_version_status),
          clone_chain_reader_(clone_chain_reader),
          current_reader_(instance_id_) {}

bool TableStreamMetadataReader::reads_from_clone_chain() const {
    return multi_version_status_ == MultiVersionStatus::MULTI_VERSION_READ_WRITE;
}

bool TableStreamMetadataReader::writes_versioned_metadata() const {
    return multi_version_status_ == MultiVersionStatus::MULTI_VERSION_WRITE_ONLY ||
           reads_from_clone_chain();
}

bool TableStreamMetadataReader::snapshot(TableStreamReadIntent intent) const {
    return intent == TableStreamReadIntent::SNAPSHOT;
}

TableStreamReadResult TableStreamMetadataReader::read_recycling_streams(
        const std::vector<int64_t>& stream_ids, TableStreamReadIntent intent,
        std::unordered_set<int64_t>* recycling_stream_ids) const {
    std::vector<std::string> keys;
    keys.reserve(stream_ids.size());
    for (int64_t stream_id : stream_ids) {
        keys.push_back(recycle_index_key({instance_id_, stream_id}));
    }

    std::vector<std::optional<std::string>> values;
    TxnErrorCode err =
            txn_->batch_get(&values, keys, Transaction::BatchGetOptions(snapshot(intent)));
    if (err != TxnErrorCode::TXN_OK) {
        return read_error(err, "Table Stream recycle indexes");
    }
    for (size_t i = 0; i < values.size(); ++i) {
        if (values[i].has_value()) {
            recycling_stream_ids->insert(stream_ids[i]);
        }
    }
    return {};
}

TableStreamReadResult TableStreamMetadataReader::read_recycling_partitions(
        const std::vector<int64_t>& partition_ids, TableStreamReadIntent intent,
        std::unordered_set<int64_t>* recycling_partition_ids) const {
    std::vector<std::string> keys;
    keys.reserve(partition_ids.size());
    for (int64_t partition_id : partition_ids) {
        keys.push_back(recycle_partition_key({instance_id_, partition_id}));
    }

    std::vector<std::optional<std::string>> values;
    TxnErrorCode err =
            txn_->batch_get(&values, keys, Transaction::BatchGetOptions(snapshot(intent)));
    if (err != TxnErrorCode::TXN_OK) {
        return read_error(err, "recycle partitions");
    }
    for (size_t i = 0; i < values.size(); ++i) {
        if (values[i].has_value()) {
            recycling_partition_ids->insert(partition_ids[i]);
        }
    }
    return {};
}

TableStreamReadResult TableStreamMetadataReader::read_and_validate_partitions(
        const std::vector<TableStreamPartitionSetPB>& bindings, TableStreamReadIntent intent,
        TableStreamPartitionVersionMap* versions,
        std::unordered_map<int64_t, std::string>* source_instances) const {
    const std::vector<int64_t> partition_ids = collect_partition_ids(bindings);
    std::unordered_set<int64_t> recycling_partition_ids;
    TableStreamReadResult result =
            read_recycling_partitions(partition_ids, intent, &recycling_partition_ids);
    if (!result.ok()) {
        return result;
    }
    if (!recycling_partition_ids.empty()) {
        return {MetaServiceCode::INVALID_ARGUMENT,
                fmt::format("partition {} is being created or recycled",
                            *recycling_partition_ids.begin())};
    }

    if (reads_from_clone_chain()) {
        DCHECK(clone_chain_reader_ != nullptr);
        std::unordered_map<int64_t, PartitionIndexPB> partition_mappings;
        TxnErrorCode err = clone_chain_reader_->get_partition_indexes(
                txn_, partition_ids, &partition_mappings, snapshot(intent));
        if (err != TxnErrorCode::TXN_OK) {
            return read_error(err, "partition mappings");
        }
        std::unordered_set<int64_t> visible_partition_ids;
        err = clone_chain_reader_->get_existing_partitions(
                txn_, partition_ids, &visible_partition_ids, snapshot(intent));
        if (err != TxnErrorCode::TXN_OK) {
            return read_error(err, "partition visibility");
        }
        for (const TableStreamPartitionSetPB& binding : bindings) {
            const TableStreamIdentityPB& identity = binding.identity();
            for (int64_t partition_id : binding.partition_ids()) {
                auto mapping_it = partition_mappings.find(partition_id);
                if (mapping_it == partition_mappings.end() ||
                    !visible_partition_ids.contains(partition_id)) {
                    return {MetaServiceCode::INVALID_ARGUMENT,
                            fmt::format("partition {} is not visible", partition_id)};
                }
                const PartitionIndexPB& mapping = mapping_it->second;
                if (!mapping.has_db_id() || mapping.db_id() != identity.base_db_id() ||
                    !mapping.has_table_id() || mapping.table_id() != identity.base_table_id()) {
                    return {MetaServiceCode::INVALID_ARGUMENT,
                            fmt::format("partition {} does not belong to base table {}",
                                        partition_id, identity.base_table_id())};
                }
            }
        }

        std::unordered_map<int64_t, VersionPB> effective_versions;
        err = clone_chain_reader_->get_partition_versions(txn_, partition_ids, &effective_versions,
                                                          nullptr, true, source_instances);
        if (err != TxnErrorCode::TXN_OK) {
            return read_error(err, "source partition versions");
        }
        for (const TableStreamPartitionSetPB& binding : bindings) {
            auto& stream_versions = (*versions)[binding.identity().stream_id()];
            for (int64_t partition_id : binding.partition_ids()) {
                auto version_it = effective_versions.find(partition_id);
                if (version_it != effective_versions.end()) {
                    stream_versions.emplace(partition_id, version_it->second);
                }
            }
        }
    } else {
        std::vector<std::string> keys;
        std::vector<std::pair<int64_t, int64_t>> positions;
        for (const TableStreamPartitionSetPB& binding : bindings) {
            const TableStreamIdentityPB& identity = binding.identity();
            for (int64_t partition_id : binding.partition_ids()) {
                keys.push_back(partition_version_key({instance_id_, identity.base_db_id(),
                                                      identity.base_table_id(), partition_id}));
                positions.emplace_back(identity.stream_id(), partition_id);
            }
        }
        std::vector<std::optional<std::string>> values;
        TxnErrorCode err = txn_->batch_get(&values, keys, Transaction::BatchGetOptions(true));
        if (err != TxnErrorCode::TXN_OK) {
            return read_error(err, "source partition versions");
        }
        for (size_t i = 0; i < values.size(); ++i) {
            if (!values[i].has_value()) {
                continue;
            }
            VersionPB version;
            if (!version.ParseFromString(*values[i])) {
                return {MetaServiceCode::PROTOBUF_PARSE_ERR,
                        fmt::format("malformed source version for partition {}",
                                    positions[i].second)};
            }
            if (source_instances) {
                (*source_instances)[positions[i].second] = instance_id_;
            }
            (*versions)[positions[i].first].emplace(positions[i].second, std::move(version));
        }
    }

    for (const TableStreamPartitionSetPB& binding : bindings) {
        auto stream_it = versions->find(binding.identity().stream_id());
        for (int64_t partition_id : binding.partition_ids()) {
            if (stream_it == versions->end()) {
                return {MetaServiceCode::VERSION_NOT_FOUND,
                        fmt::format("source version is missing for partition {}", partition_id)};
            }
            auto version_it = stream_it->second.find(partition_id);
            if (version_it == stream_it->second.end() ||
                (!version_it->second.has_version() &&
                 version_it->second.pending_txn_ids().empty()) ||
                !version_it->second.has_commit_tso()) {
                return {MetaServiceCode::VERSION_NOT_FOUND,
                        fmt::format("source version or commit TSO is missing for partition {}",
                                    partition_id)};
            }
        }
    }
    return {};
}

TableStreamReadResult TableStreamMetadataReader::read_latest_offsets(
        const std::vector<TableStreamPartitionSetPB>& bindings, TableStreamReadIntent intent,
        TableStreamOffsetMap* offsets) const {
    std::vector<std::string> keys;
    std::vector<std::pair<int64_t, int64_t>> positions;
    for (const TableStreamPartitionSetPB& binding : bindings) {
        const TableStreamIdentityPB& identity = binding.identity();
        for (int64_t partition_id : binding.partition_ids()) {
            keys.push_back(table_stream_offset_key(
                    {instance_id_, identity.base_db_id(), identity.base_table_id(),
                     identity.stream_db_id(), identity.stream_id(), partition_id}));
            positions.emplace_back(identity.stream_id(), partition_id);
        }
    }

    std::vector<std::optional<std::string>> values;
    TxnErrorCode err =
            txn_->batch_get(&values, keys, Transaction::BatchGetOptions(snapshot(intent)));
    if (err != TxnErrorCode::TXN_OK) {
        return read_error(err, "latest Table Stream offsets");
    }
    for (size_t i = 0; i < values.size(); ++i) {
        if (!values[i].has_value()) {
            continue;
        }
        TableStreamOffsetPB offset;
        if (!offset.ParseFromString(*values[i])) {
            return {MetaServiceCode::PROTOBUF_PARSE_ERR,
                    fmt::format("malformed Table Stream offset for partition {}",
                                positions[i].second)};
        }
        (*offsets)[positions[i].first].emplace(positions[i].second, std::move(offset));
    }
    return {};
}

TableStreamReadResult TableStreamMetadataReader::read_effective_offsets(
        const std::vector<TableStreamPartitionSetPB>& bindings, TableStreamReadIntent intent,
        TableStreamOffsetMap* offsets) const {
    if (!reads_from_clone_chain()) {
        return read_latest_offsets(bindings, intent, offsets);
    }

    TableStreamOffsetMap local_offsets;
    if (intent == TableStreamReadIntent::CONFLICT) {
        TableStreamReadResult result = read_latest_offsets(bindings, intent, &local_offsets);
        if (!result.ok()) {
            return result;
        }
    }

    DCHECK(clone_chain_reader_ != nullptr);
    TxnErrorCode err = clone_chain_reader_->get_table_stream_offsets(txn_, bindings, offsets,
                                                                     nullptr, snapshot(intent));
    if (err != TxnErrorCode::TXN_OK) {
        return read_error(err, "effective Table Stream offsets");
    }

    for (const auto& [stream_id, partition_offsets] : local_offsets) {
        auto effective_stream_it = offsets->find(stream_id);
        for (const auto& [partition_id, local_offset] : partition_offsets) {
            if (effective_stream_it == offsets->end()) {
                return {MetaServiceCode::INVALID_ARGUMENT,
                        fmt::format("local Table Stream offset exists without an effective offset "
                                    "for stream {} partition {}",
                                    stream_id, partition_id)};
            }
            auto effective_offset_it = effective_stream_it->second.find(partition_id);
            if (effective_offset_it == effective_stream_it->second.end()) {
                return {MetaServiceCode::INVALID_ARGUMENT,
                        fmt::format("local Table Stream offset exists without an effective offset "
                                    "for stream {} partition {}",
                                    stream_id, partition_id)};
            }
            if (local_offset.SerializeAsString() !=
                effective_offset_it->second.SerializeAsString()) {
                return {MetaServiceCode::INVALID_ARGUMENT,
                        fmt::format("local and effective Table Stream offsets differ for stream {} "
                                    "partition {}",
                                    stream_id, partition_id)};
            }
        }
    }
    return {};
}

TableStreamReadResult TableStreamMetadataReader::read_local_versioned_offsets(
        const std::vector<TableStreamPartitionSetPB>& bindings, TableStreamReadIntent intent,
        TableStreamOffsetMap* offsets) const {
    TxnErrorCode err = current_reader_.get_table_stream_offsets(txn_, bindings, offsets, nullptr,
                                                                snapshot(intent));
    return err == TxnErrorCode::TXN_OK ? TableStreamReadResult {}
                                       : read_error(err, "local versioned Table Stream offsets");
}

} // namespace doris::cloud
