#ifndef COMPONENTS_DATA_SHARING_INTERNAL_GROUP_DATA_MODEL_H_
#define COMPONENTS_DATA_SHARING_INTERNAL_GROUP_DATA_MODEL_H_
#include <vector>
#include "base/files/file_path.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/time/time.h"
#include "components/data_sharing/internal/collaboration_group_sync_bridge.h"
#include "components/data_sharing/internal/group_data_store.h"
#include "components/data_sharing/public/data_sharing_sdk_delegate.h"
#include "components/data_sharing/public/group_data.h"
#include "components/data_sharing/public/protocol/data_sharing_sdk.pb.h"
class GaiaId;
namespace data_sharing {
class GroupDataModel : public CollaborationGroupSyncBridge::Observer {
public:
class Observer : public base::CheckedObserver {
public:
Observer() = default;
~Observer() override = default;
virtual void OnModelLoaded() = 0;
virtual void OnGroupAdded(const GroupId& group_id,
const base::Time& event_time) = 0;
virtual void OnGroupUpdated(const GroupId& group_id,
const base::Time& event_time) = 0;
virtual void OnGroupDeleted(const GroupId& group_id,
const std::optional<GroupData>& group_data,
const base::Time& event_time) = 0;
virtual void OnMemberAdded(const GroupId& group_id,
const GaiaId& member_gaia_id,
const base::Time& event_time) = 0;
virtual void OnMemberRemoved(const GroupId& group_id,
const GaiaId& member_gaia_id,
const base::Time& event_time) = 0;
virtual void OnSyncBridgeUpdateTypeChanged(
SyncBridgeUpdateType sync_bridge_update_type) = 0;
};
GroupDataModel(const base::FilePath& data_sharing_dir,
CollaborationGroupSyncBridge* collaboration_group_sync_bridge,
DataSharingSDKDelegate* sdk_delegate);
~GroupDataModel() override;
GroupDataModel(const GroupDataModel&) = delete;
GroupDataModel& operator=(const GroupDataModel&) = delete;
GroupDataModel(GroupDataModel&&) = delete;
GroupDataModel& operator=(GroupDataModel&&) = delete;
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
bool IsModelLoaded() const;
std::optional<GroupData> GetGroup(const GroupId& group_id) const;
std::set<GroupData> GetAllGroups() const;
std::optional<GroupMemberPartialData> GetPossiblyRemovedGroupMember(
const GroupId& group_id,
const GaiaId& member_gaia_id) const;
std::vector<GroupEvent> GetGroupEventsSinceStartup() const;
void OnGroupsUpdated(const std::vector<GroupId>& added_group_ids,
const std::vector<GroupId>& updated_group_ids,
const std::vector<GroupId>& deleted_group_ids) override;
void OnCollaborationGroupSyncDataLoaded() override;
void OnSyncBridgeUpdateTypeChanged(
SyncBridgeUpdateType sync_bridge_update_type) override;
GroupDataStore& GetGroupDataStoreForTesting();
void SetGroupDataStoreLoadedCallbackForTesting(
base::OnceClosure db_loaded_callback);
private:
void OnGroupDataStoreLoaded(GroupDataStore::DBInitStatus status);
void ProcessGroupChanges(bool is_initial_load);
void DoPeriodicPollingAndScheduleNext();
void ScheduleNextPeriodicPolling();
void FetchGroupsFromSDK(const std::vector<GroupId>& added_or_updated_groups);
void OnBatchOfGroupsFetchedFromSDK(
const std::map<GroupId, VersionToken>& requested_groups_and_versions,
const base::Time& requested_at_timestamp,
const base::expected<data_sharing_pb::ReadGroupsResult, absl::Status>&
read_groups_result);
void FetchBatchOfGroupsFromSDK(const std::vector<GroupId>& batch);
void HandleBatchCompletion();
void NotifyObserversAboutChangedMembers(const GroupData& old_group_data,
const GroupData& new_group_data);
void MaybeRecordGroupEvent(
const GroupId& group_id,
GroupEvent::EventType event_type,
base::Time event_time,
std::optional<GaiaId> affected_member_gaia_id = std::nullopt);
GroupDataStore group_data_store_;
bool is_group_data_store_loaded_ = false;
bool is_collaboration_group_bridge_loaded_ = false;
bool has_ongoing_group_fetch_ = false;
bool has_pending_changes_ = false;
int outstanding_batches_ = 0;
std::vector<GroupEvent> group_events_since_startup_;
raw_ptr<CollaborationGroupSyncBridge> collaboration_group_sync_bridge_;
raw_ptr<DataSharingSDKDelegate> sdk_delegate_;
base::OnceClosure db_loaded_callback_;
base::OneShotTimer next_periodic_polling_timer_;
base::ObserverList<Observer> observers_;
base::WeakPtrFactory<GroupDataModel> weak_ptr_factory_{this};
};
}
#endif