// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sync/sessions/sync_session.h"

#include <algorithm>
#include <iterator>

#include "base/logging.h"
#include "sync/internal_api/public/base/model_type.h"
#include "sync/internal_api/public/engine/model_safe_worker.h"
#include "sync/syncable/directory.h"

namespace syncer {
namespace sessions {

// static
SyncSession* SyncSession::Build(SyncSessionContext* context,
                                Delegate* delegate) {
  return new SyncSession(context, delegate);
}

SyncSession::SyncSession(
    SyncSessionContext* context,
    Delegate* delegate)
    : context_(context),
      delegate_(delegate) {
  status_controller_.reset(new StatusController());
}

SyncSession::~SyncSession() {}

SyncSessionSnapshot SyncSession::TakeSnapshot() const {
  return TakeSnapshotWithSource(sync_pb::GetUpdatesCallerInfo::UNKNOWN);
}

SyncSessionSnapshot SyncSession::TakeSnapshotWithSource(
  sync_pb::GetUpdatesCallerInfo::GetUpdatesSource legacy_updates_source) const {
  syncable::Directory* dir = context_->directory();

  ProgressMarkerMap download_progress_markers;
  for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) {
    ModelType type(ModelTypeFromInt(i));
    dir->GetDownloadProgressAsString(type, &download_progress_markers[type]);
  }

  std::vector<int> num_entries_by_type(MODEL_TYPE_COUNT, 0);
  std::vector<int> num_to_delete_entries_by_type(MODEL_TYPE_COUNT, 0);
  dir->CollectMetaHandleCounts(&num_entries_by_type,
                               &num_to_delete_entries_by_type);

  SyncSessionSnapshot snapshot(
      status_controller_->model_neutral_state(),
      download_progress_markers,
      delegate_->IsCurrentlyThrottled(),
      status_controller_->num_encryption_conflicts(),
      status_controller_->num_hierarchy_conflicts(),
      status_controller_->num_server_conflicts(),
      context_->notifications_enabled(),
      dir->GetEntriesCount(),
      status_controller_->sync_start_time(),
      num_entries_by_type,
      num_to_delete_entries_by_type,
      legacy_updates_source);

  return snapshot;
}

void SyncSession::SendSyncCycleEndEventNotification(
    sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source) {
  SyncEngineEvent event(SyncEngineEvent::SYNC_CYCLE_ENDED);
  event.snapshot = TakeSnapshotWithSource(source);

  DVLOG(1) << "Sending cycle end event with snapshot: "
      << event.snapshot.ToString();
  context()->NotifyListeners(event);
}

void SyncSession::SendEventNotification(SyncEngineEvent::EventCause cause) {
  SyncEngineEvent event(cause);
  event.snapshot = TakeSnapshot();

  DVLOG(1) << "Sending event with snapshot: " << event.snapshot.ToString();
  context()->NotifyListeners(event);
}

}  // namespace sessions
}  // namespace syncer
