153c3577eSopenharmony_ci/*
253c3577eSopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
353c3577eSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
453c3577eSopenharmony_ci * you may not use this file except in compliance with the License.
553c3577eSopenharmony_ci * You may obtain a copy of the License at
653c3577eSopenharmony_ci *
753c3577eSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
853c3577eSopenharmony_ci *
953c3577eSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1053c3577eSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1153c3577eSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1253c3577eSopenharmony_ci * See the License for the specific language governing permissions and
1353c3577eSopenharmony_ci * limitations under the License.
1453c3577eSopenharmony_ci */
1553c3577eSopenharmony_ci
1653c3577eSopenharmony_ci#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_SYNC_MANAGER_H
1753c3577eSopenharmony_ci#define OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_SYNC_MANAGER_H
1853c3577eSopenharmony_ci
1953c3577eSopenharmony_ci#include "cloud/cloud_event.h"
2053c3577eSopenharmony_ci#include "cloud/cloud_info.h"
2153c3577eSopenharmony_ci#include "cloud/sync_strategy.h"
2253c3577eSopenharmony_ci#include "cloud_types.h"
2353c3577eSopenharmony_ci#include "concurrent_map.h"
2453c3577eSopenharmony_ci#include "eventcenter/event.h"
2553c3577eSopenharmony_ci#include "executor_pool.h"
2653c3577eSopenharmony_ci#include "metadata/store_meta_data_local.h"
2753c3577eSopenharmony_ci#include "store/auto_cache.h"
2853c3577eSopenharmony_ci#include "store/general_store.h"
2953c3577eSopenharmony_ci#include "store/general_value.h"
3053c3577eSopenharmony_ci#include "utils/ref_count.h"
3153c3577eSopenharmony_ci
3253c3577eSopenharmony_cinamespace OHOS::CloudData {
3353c3577eSopenharmony_ciclass SyncManager {
3453c3577eSopenharmony_cipublic:
3553c3577eSopenharmony_ci    using GenAsync = DistributedData::GenAsync;
3653c3577eSopenharmony_ci    using GenStore = DistributedData::GeneralStore;
3753c3577eSopenharmony_ci    using GenQuery = DistributedData::GenQuery;
3853c3577eSopenharmony_ci    using RefCount = DistributedData::RefCount;
3953c3577eSopenharmony_ci    using AutoCache = DistributedData::AutoCache;
4053c3577eSopenharmony_ci    using StoreMetaData = DistributedData::StoreMetaData;
4153c3577eSopenharmony_ci    using SchemaMeta = DistributedData::SchemaMeta;
4253c3577eSopenharmony_ci    using TraceIds = std::map<std::string, std::string>;
4353c3577eSopenharmony_ci    using SyncStage = DistributedData::SyncStage;
4453c3577eSopenharmony_ci    using ReportParam = DistributedData::ReportParam;
4553c3577eSopenharmony_ci    static AutoCache::Store GetStore(const StoreMetaData &meta, int32_t user, bool mustBind = true);
4653c3577eSopenharmony_ci    class SyncInfo final {
4753c3577eSopenharmony_ci    public:
4853c3577eSopenharmony_ci        using Store = std::string;
4953c3577eSopenharmony_ci        using Stores = std::vector<Store>;
5053c3577eSopenharmony_ci        using Tables = std::vector<std::string>;
5153c3577eSopenharmony_ci        struct Param {
5253c3577eSopenharmony_ci            int32_t user;
5353c3577eSopenharmony_ci            std::string bundleName;
5453c3577eSopenharmony_ci            Store store;
5553c3577eSopenharmony_ci            Tables tables;
5653c3577eSopenharmony_ci            int32_t triggerMode = 0;
5753c3577eSopenharmony_ci            std::string prepareTraceId;
5853c3577eSopenharmony_ci        };
5953c3577eSopenharmony_ci        using MutliStoreTables = std::map<Store, Tables>;
6053c3577eSopenharmony_ci        explicit SyncInfo(int32_t user, const std::string &bundleName = "", const Store &store = "",
6153c3577eSopenharmony_ci            const Tables &tables = {}, int32_t triggerMode = 0);
6253c3577eSopenharmony_ci        SyncInfo(int32_t user, const std::string &bundleName, const Stores &stores);
6353c3577eSopenharmony_ci        SyncInfo(int32_t user, const std::string &bundleName, const MutliStoreTables &tables);
6453c3577eSopenharmony_ci        explicit SyncInfo(const Param &param);
6553c3577eSopenharmony_ci        void SetMode(int32_t mode);
6653c3577eSopenharmony_ci        void SetWait(int32_t wait);
6753c3577eSopenharmony_ci        void SetAsyncDetail(GenAsync asyncDetail);
6853c3577eSopenharmony_ci        void SetQuery(std::shared_ptr<GenQuery> query);
6953c3577eSopenharmony_ci        void SetError(int32_t code) const;
7053c3577eSopenharmony_ci        void SetCompensation(bool isCompensation);
7153c3577eSopenharmony_ci        void SetTriggerMode(int32_t triggerMode);
7253c3577eSopenharmony_ci        void SetPrepareTraceId(const std::string &prepareTraceId);
7353c3577eSopenharmony_ci        std::shared_ptr<GenQuery> GenerateQuery(const std::string &store, const Tables &tables);
7453c3577eSopenharmony_ci        bool Contains(const std::string &storeName);
7553c3577eSopenharmony_ci        inline static constexpr const char *DEFAULT_ID = "default";
7653c3577eSopenharmony_ci
7753c3577eSopenharmony_ci    private:
7853c3577eSopenharmony_ci        friend SyncManager;
7953c3577eSopenharmony_ci        uint64_t syncId_ = 0;
8053c3577eSopenharmony_ci        int32_t mode_ = GenStore::MixMode(GenStore::CLOUD_TIME_FIRST, GenStore::AUTO_SYNC_MODE);
8153c3577eSopenharmony_ci        int32_t user_ = 0;
8253c3577eSopenharmony_ci        int32_t wait_ = 0;
8353c3577eSopenharmony_ci        std::string id_ = DEFAULT_ID;
8453c3577eSopenharmony_ci        std::string bundleName_;
8553c3577eSopenharmony_ci        std::map<std::string, std::vector<std::string>> tables_;
8653c3577eSopenharmony_ci        GenAsync async_;
8753c3577eSopenharmony_ci        std::shared_ptr<GenQuery> query_;
8853c3577eSopenharmony_ci        bool isCompensation_ = false;
8953c3577eSopenharmony_ci        int32_t triggerMode_ = 0;
9053c3577eSopenharmony_ci        std::string prepareTraceId_;
9153c3577eSopenharmony_ci    };
9253c3577eSopenharmony_ci    SyncManager();
9353c3577eSopenharmony_ci    ~SyncManager();
9453c3577eSopenharmony_ci    int32_t Bind(std::shared_ptr<ExecutorPool> executor);
9553c3577eSopenharmony_ci    int32_t DoCloudSync(SyncInfo syncInfo);
9653c3577eSopenharmony_ci    int32_t StopCloudSync(int32_t user = 0);
9753c3577eSopenharmony_ci    int32_t QueryLastSyncInfo(const std::vector<QueryKey> &queryKeys, QueryLastResults &results);
9853c3577eSopenharmony_ci    void Report(const ReportParam &reportParam);
9953c3577eSopenharmony_ci
10053c3577eSopenharmony_ciprivate:
10153c3577eSopenharmony_ci    using Event = DistributedData::Event;
10253c3577eSopenharmony_ci    using Task = ExecutorPool::Task;
10353c3577eSopenharmony_ci    using TaskId = ExecutorPool::TaskId;
10453c3577eSopenharmony_ci    using Duration = ExecutorPool::Duration;
10553c3577eSopenharmony_ci    using Retryer =
10653c3577eSopenharmony_ci        std::function<bool(Duration interval, int32_t status, int32_t dbCode, const std::string &prepareTraceId)>;
10753c3577eSopenharmony_ci    using CloudInfo = DistributedData::CloudInfo;
10853c3577eSopenharmony_ci    using StoreInfo = DistributedData::StoreInfo;
10953c3577eSopenharmony_ci    using SyncStrategy = DistributedData::SyncStrategy;
11053c3577eSopenharmony_ci    using SyncId = uint64_t;
11153c3577eSopenharmony_ci    using GeneralError = DistributedData::GeneralError;
11253c3577eSopenharmony_ci    using GenProgress = DistributedData::GenProgress;
11353c3577eSopenharmony_ci    using GenDetails = DistributedData::GenDetails;
11453c3577eSopenharmony_ci
11553c3577eSopenharmony_ci    static constexpr ExecutorPool::Duration RETRY_INTERVAL = std::chrono::seconds(10);  // second
11653c3577eSopenharmony_ci    static constexpr ExecutorPool::Duration LOCKED_INTERVAL = std::chrono::seconds(30); // second
11753c3577eSopenharmony_ci    static constexpr ExecutorPool::Duration BUSY_INTERVAL = std::chrono::seconds(180);  // second
11853c3577eSopenharmony_ci    static constexpr int32_t RETRY_TIMES = 6;                                           // normal retry
11953c3577eSopenharmony_ci    static constexpr int32_t CLIENT_RETRY_TIMES = 3;                                    // normal retry
12053c3577eSopenharmony_ci    static constexpr uint64_t USER_MARK = 0xFFFFFFFF00000000;                           // high 32 bit
12153c3577eSopenharmony_ci    static constexpr int32_t MV_BIT = 32;
12253c3577eSopenharmony_ci    static constexpr int32_t EXPIRATION_TIME = 6 * 60 * 60 * 1000;                      // 6 hours
12353c3577eSopenharmony_ci
12453c3577eSopenharmony_ci    static uint64_t GenerateId(int32_t user);
12553c3577eSopenharmony_ci    static ExecutorPool::Duration GetInterval(int32_t code);
12653c3577eSopenharmony_ci    static std::map<uint32_t, GenStore::BindInfo> GetBindInfos(
12753c3577eSopenharmony_ci        const StoreMetaData &meta, const std::vector<int32_t> &users, const DistributedData::Database &schemaDatabase);
12853c3577eSopenharmony_ci    static std::string GetAccountId(int32_t user);
12953c3577eSopenharmony_ci    static std::vector<std::tuple<QueryKey, uint64_t>> GetCloudSyncInfo(const SyncInfo &info, CloudInfo &cloud);
13053c3577eSopenharmony_ci    static std::vector<SchemaMeta> GetSchemaMeta(const CloudInfo &cloud, const std::string &bundleName);
13153c3577eSopenharmony_ci    static bool NeedGetCloudInfo(CloudInfo &cloud);
13253c3577eSopenharmony_ci    static GeneralError IsValid(SyncInfo &info, CloudInfo &cloud);
13353c3577eSopenharmony_ci    Task GetSyncTask(int32_t times, bool retry, RefCount ref, SyncInfo &&syncInfo);
13453c3577eSopenharmony_ci    void UpdateSchema(const SyncInfo &syncInfo);
13553c3577eSopenharmony_ci    std::function<void(const Event &)> GetSyncHandler(Retryer retryer);
13653c3577eSopenharmony_ci    std::function<void(const Event &)> GetClientChangeHandler();
13753c3577eSopenharmony_ci    Retryer GetRetryer(int32_t times, const SyncInfo &syncInfo, int32_t user);
13853c3577eSopenharmony_ci    RefCount GenSyncRef(uint64_t syncId);
13953c3577eSopenharmony_ci    int32_t Compare(uint64_t syncId, int32_t user);
14053c3577eSopenharmony_ci    void UpdateStartSyncInfo(const std::vector<std::tuple<QueryKey, uint64_t>> &cloudSyncInfos);
14153c3577eSopenharmony_ci    void UpdateFinishSyncInfo(const QueryKey &queryKey, uint64_t syncId, int32_t code);
14253c3577eSopenharmony_ci    std::function<void(const DistributedData::GenDetails &result)> GetCallback(const GenAsync &async,
14353c3577eSopenharmony_ci        const StoreInfo &storeInfo, int32_t triggerMode, const std::string &prepareTraceId, int32_t user);
14453c3577eSopenharmony_ci    std::function<void()> GetPostEventTask(const std::vector<SchemaMeta> &schemas, CloudInfo &cloud, SyncInfo &info,
14553c3577eSopenharmony_ci        bool retry, const TraceIds &traceIds);
14653c3577eSopenharmony_ci    void DoExceptionalCallback(
14753c3577eSopenharmony_ci        const GenAsync &async, GenDetails &details, const StoreInfo &storeInfo, const std::string &prepareTraceId);
14853c3577eSopenharmony_ci    bool InitDefaultUser(int32_t &user);
14953c3577eSopenharmony_ci    std::function<void(const DistributedData::GenDetails &result)> RetryCallback(const StoreInfo &storeInfo,
15053c3577eSopenharmony_ci        Retryer retryer, int32_t triggerMode, const std::string &prepareTraceId, int32_t user);
15153c3577eSopenharmony_ci    static void GetLastResults(
15253c3577eSopenharmony_ci        const std::string &storeId, std::map<SyncId, CloudSyncInfo> &infos, QueryLastResults &results);
15353c3577eSopenharmony_ci    void BatchUpdateFinishState(const std::vector<std::tuple<QueryKey, uint64_t>> &cloudSyncInfos, int32_t code);
15453c3577eSopenharmony_ci    bool NeedSaveSyncInfo(const QueryKey &queryKey);
15553c3577eSopenharmony_ci    std::function<void(const Event &)> GetLockChangeHandler();
15653c3577eSopenharmony_ci    void BatchReport(int32_t userId, const TraceIds &traceIds, SyncStage syncStage, int32_t errCode);
15753c3577eSopenharmony_ci    TraceIds GetPrepareTraceId(const SyncInfo &info, const CloudInfo &cloud);
15853c3577eSopenharmony_ci    std::pair<bool, StoreMetaData> GetMetaData(const StoreInfo &storeInfo);
15953c3577eSopenharmony_ci
16053c3577eSopenharmony_ci    static std::atomic<uint32_t> genId_;
16153c3577eSopenharmony_ci    std::shared_ptr<ExecutorPool> executor_;
16253c3577eSopenharmony_ci    ConcurrentMap<uint64_t, TaskId> actives_;
16353c3577eSopenharmony_ci    ConcurrentMap<uint64_t, uint64_t> activeInfos_;
16453c3577eSopenharmony_ci    std::shared_ptr<SyncStrategy> syncStrategy_;
16553c3577eSopenharmony_ci    ConcurrentMap<QueryKey, std::map<SyncId, CloudSyncInfo>> lastSyncInfos_;
16653c3577eSopenharmony_ci    std::set<std::string> kvApps_;
16753c3577eSopenharmony_ci};
16853c3577eSopenharmony_ci} // namespace OHOS::CloudData
16953c3577eSopenharmony_ci#endif // OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_SYNC_MANAGER_H