/*
 * Copyright (C) 2024 KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */

#pragma once

#include <Database.h>

#include <shared_mutex>

namespace scene {
class VectorDatabase {
public:
    static VectorDatabase& getInstance();

    bool connect();
    // 快速创建 collection 方式，主键名称：id，DataType::INT64，向量列：vector，DataType::FLOAT_VECTOR
    bool createCollection(const std::string& name, int dimension, bool autoId = true, bool enableDynamicField = true);

    bool createCollection(const VectorDB::CollectionSchema& schema, const VectorDB::IndexDesc& desc);

    bool dropCollection(const std::string& name);

    bool insert(const std::string& name, const std::vector<VectorDB::FieldDataPtr>& fields,
                VectorDB::DmlResults& results);

    bool search(const VectorDB::SearchArguments& arguments, VectorDB::SearchResults& results, int timeout = 0);

    bool query(const VectorDB::QueryArguments& arguments, VectorDB::QueryResults& results, int timeout = 0);

    bool upsert(const std::string& name, const std::vector<VectorDB::FieldDataPtr>& fields,
                VectorDB::DmlResults& results);

    bool deleteData(const std::string& name, const std::string& expression, VectorDB::DmlResults& results);

    bool disconnect();

    bool hasCollection(const std::string& name);

private:
    VectorDatabase();

    static bool checkStatus(std::string&& prefix, const VectorDB::Status& status);

    bool getConnection();

    ~VectorDatabase();

private:
    std::shared_ptr<VectorDB::Database> client;

    std::shared_mutex mtx;
    bool isConnected;  // 目前只支持一个连接，后续场景需要多个连接再升级连接池
};

#define GET_CONNECTION()    \
    if (!getConnection()) { \
        return false;       \
    }

}  // namespace scene
