// 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/internal_api/debug_info_event_listener.h"

#include "sync/notifier/object_id_invalidation_map.h"
#include "sync/util/cryptographer.h"

namespace syncer {

using sessions::SyncSessionSnapshot;

DebugInfoEventListener::DebugInfoEventListener()
    : events_dropped_(false),
      cryptographer_has_pending_keys_(false),
      cryptographer_ready_(false),
      weak_ptr_factory_(this) {
}

DebugInfoEventListener::~DebugInfoEventListener() {
}

void DebugInfoEventListener::OnSyncCycleCompleted(
    const SyncSessionSnapshot& snapshot) {
  DCHECK(thread_checker_.CalledOnValidThread());
  sync_pb::DebugEventInfo event_info;
  sync_pb::SyncCycleCompletedEventInfo* sync_completed_event_info =
      event_info.mutable_sync_cycle_completed_event_info();

  sync_completed_event_info->set_num_encryption_conflicts(
      snapshot.num_encryption_conflicts());
  sync_completed_event_info->set_num_hierarchy_conflicts(
      snapshot.num_hierarchy_conflicts());
  sync_completed_event_info->set_num_server_conflicts(
      snapshot.num_server_conflicts());

  sync_completed_event_info->set_num_updates_downloaded(
      snapshot.model_neutral_state().num_updates_downloaded_total);
  sync_completed_event_info->set_num_reflected_updates_downloaded(
      snapshot.model_neutral_state().num_reflected_updates_downloaded_total);
  sync_completed_event_info->mutable_caller_info()->set_source(
      snapshot.legacy_updates_source());
  sync_completed_event_info->mutable_caller_info()->set_notifications_enabled(
      snapshot.notifications_enabled());

  AddEventToQueue(event_info);
}

void DebugInfoEventListener::OnInitializationComplete(
    const WeakHandle<JsBackend>& js_backend,
    const WeakHandle<DataTypeDebugInfoListener>& debug_listener,
    bool success, ModelTypeSet restored_types) {
  DCHECK(thread_checker_.CalledOnValidThread());
  CreateAndAddEvent(sync_pb::SyncEnums::INITIALIZATION_COMPLETE);
}

void DebugInfoEventListener::OnConnectionStatusChange(
    ConnectionStatus status) {
  DCHECK(thread_checker_.CalledOnValidThread());
  CreateAndAddEvent(sync_pb::SyncEnums::CONNECTION_STATUS_CHANGE);
}

void DebugInfoEventListener::OnPassphraseRequired(
    PassphraseRequiredReason reason,
    const sync_pb::EncryptedData& pending_keys) {
  DCHECK(thread_checker_.CalledOnValidThread());
  CreateAndAddEvent(sync_pb::SyncEnums::PASSPHRASE_REQUIRED);
}

void DebugInfoEventListener::OnPassphraseAccepted() {
  DCHECK(thread_checker_.CalledOnValidThread());
  CreateAndAddEvent(sync_pb::SyncEnums::PASSPHRASE_ACCEPTED);
}

void DebugInfoEventListener::OnBootstrapTokenUpdated(
    const std::string& bootstrap_token, BootstrapTokenType type) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (type == PASSPHRASE_BOOTSTRAP_TOKEN) {
    CreateAndAddEvent(sync_pb::SyncEnums::BOOTSTRAP_TOKEN_UPDATED);
    return;
  }
  DCHECK_EQ(type, KEYSTORE_BOOTSTRAP_TOKEN);
  CreateAndAddEvent(sync_pb::SyncEnums::KEYSTORE_TOKEN_UPDATED);
}

void DebugInfoEventListener::OnEncryptedTypesChanged(
    ModelTypeSet encrypted_types,
    bool encrypt_everything) {
  DCHECK(thread_checker_.CalledOnValidThread());
  CreateAndAddEvent(sync_pb::SyncEnums::ENCRYPTED_TYPES_CHANGED);
}

void DebugInfoEventListener::OnEncryptionComplete() {
  DCHECK(thread_checker_.CalledOnValidThread());
  CreateAndAddEvent(sync_pb::SyncEnums::ENCRYPTION_COMPLETE);
}

void DebugInfoEventListener::OnCryptographerStateChanged(
    Cryptographer* cryptographer) {
  DCHECK(thread_checker_.CalledOnValidThread());
  cryptographer_has_pending_keys_ = cryptographer->has_pending_keys();
  cryptographer_ready_ = cryptographer->is_ready();
}

void DebugInfoEventListener::OnPassphraseTypeChanged(
    PassphraseType type,
    base::Time explicit_passphrase_time) {
  DCHECK(thread_checker_.CalledOnValidThread());
  CreateAndAddEvent(sync_pb::SyncEnums::PASSPHRASE_TYPE_CHANGED);
}

void DebugInfoEventListener::OnActionableError(
    const SyncProtocolError& sync_error) {
  DCHECK(thread_checker_.CalledOnValidThread());
  CreateAndAddEvent(sync_pb::SyncEnums::ACTIONABLE_ERROR);
}

void DebugInfoEventListener::OnMigrationRequested(ModelTypeSet types) {}

void DebugInfoEventListener::OnProtocolEvent(const ProtocolEvent& event) {}

void DebugInfoEventListener::OnNudgeFromDatatype(ModelType datatype) {
  DCHECK(thread_checker_.CalledOnValidThread());
  sync_pb::DebugEventInfo event_info;
  event_info.set_nudging_datatype(
      GetSpecificsFieldNumberFromModelType(datatype));
  AddEventToQueue(event_info);
}

void DebugInfoEventListener::OnIncomingNotification(
    const ObjectIdInvalidationMap& invalidation_map) {
  DCHECK(thread_checker_.CalledOnValidThread());
  sync_pb::DebugEventInfo event_info;
  ModelTypeSet types =
      ObjectIdSetToModelTypeSet(invalidation_map.GetObjectIds());

  for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
    event_info.add_datatypes_notified_from_server(
        GetSpecificsFieldNumberFromModelType(it.Get()));
  }

  AddEventToQueue(event_info);
}

void DebugInfoEventListener::GetDebugInfo(sync_pb::DebugInfo* debug_info) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_LE(events_.size(), kMaxEntries);

  for (DebugEventInfoQueue::const_iterator iter = events_.begin();
       iter != events_.end();
       ++iter) {
    sync_pb::DebugEventInfo* event_info = debug_info->add_events();
    event_info->CopyFrom(*iter);
  }

  debug_info->set_events_dropped(events_dropped_);
  debug_info->set_cryptographer_ready(cryptographer_ready_);
  debug_info->set_cryptographer_has_pending_keys(
      cryptographer_has_pending_keys_);
}

void DebugInfoEventListener::ClearDebugInfo() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_LE(events_.size(), kMaxEntries);

  events_.clear();
  events_dropped_ = false;
}

base::WeakPtr<DataTypeDebugInfoListener> DebugInfoEventListener::GetWeakPtr() {
  DCHECK(thread_checker_.CalledOnValidThread());
  return weak_ptr_factory_.GetWeakPtr();
}

void DebugInfoEventListener::OnDataTypeConfigureComplete(
    const std::vector<DataTypeConfigurationStats>& configuration_stats) {
  DCHECK(thread_checker_.CalledOnValidThread());

  for (size_t i = 0; i < configuration_stats.size(); ++i) {
    DCHECK(ProtocolTypes().Has(configuration_stats[i].model_type));
    const DataTypeAssociationStats& association_stats =
        configuration_stats[i].association_stats;

    sync_pb::DebugEventInfo association_event;
    sync_pb::DatatypeAssociationStats* datatype_stats =
        association_event.mutable_datatype_association_stats();
    datatype_stats->set_data_type_id(
        GetSpecificsFieldNumberFromModelType(
            configuration_stats[i].model_type));
    datatype_stats->set_num_local_items_before_association(
        association_stats.num_local_items_before_association);
    datatype_stats->set_num_sync_items_before_association(
        association_stats.num_sync_items_before_association);
    datatype_stats->set_num_local_items_after_association(
        association_stats.num_local_items_after_association);
    datatype_stats->set_num_sync_items_after_association(
        association_stats.num_sync_items_after_association);
    datatype_stats->set_num_local_items_added(
        association_stats.num_local_items_added);
    datatype_stats->set_num_local_items_deleted(
        association_stats.num_local_items_deleted);
    datatype_stats->set_num_local_items_modified(
        association_stats.num_local_items_modified);
    datatype_stats->set_num_sync_items_added(
        association_stats.num_sync_items_added);
    datatype_stats->set_num_sync_items_deleted(
        association_stats.num_sync_items_deleted);
    datatype_stats->set_num_sync_items_modified(
        association_stats.num_sync_items_modified);
    datatype_stats->set_local_version_pre_association(
        association_stats.local_version_pre_association);
    datatype_stats->set_sync_version_pre_association(
        association_stats.sync_version_pre_association);
    datatype_stats->set_had_error(association_stats.had_error);
    datatype_stats->set_association_wait_time_for_same_priority_us(
          association_stats.association_wait_time.InMicroseconds());
    datatype_stats->set_association_time_us(
        association_stats.association_time.InMicroseconds());
    datatype_stats->set_download_wait_time_us(
        configuration_stats[i].download_wait_time.InMicroseconds());
    datatype_stats->set_download_time_us(
        configuration_stats[i].download_time.InMicroseconds());
    datatype_stats->set_association_wait_time_for_high_priority_us(
        configuration_stats[i].association_wait_time_for_high_priority
            .InMicroseconds());

    for (ModelTypeSet::Iterator it =
             configuration_stats[i].high_priority_types_configured_before
                 .First();
         it.Good(); it.Inc()) {
      datatype_stats->add_high_priority_type_configured_before(
          GetSpecificsFieldNumberFromModelType(it.Get()));
    }

    for (ModelTypeSet::Iterator it =
             configuration_stats[i].same_priority_types_configured_before
                 .First();
        it.Good(); it.Inc()) {
      datatype_stats->add_same_priority_type_configured_before(
          GetSpecificsFieldNumberFromModelType(it.Get()));
    }

    AddEventToQueue(association_event);
  }
}

void DebugInfoEventListener::CreateAndAddEvent(
    sync_pb::SyncEnums::SingletonDebugEventType type) {
  DCHECK(thread_checker_.CalledOnValidThread());
  sync_pb::DebugEventInfo event_info;
  event_info.set_singleton_event(type);
  AddEventToQueue(event_info);
}

void DebugInfoEventListener::AddEventToQueue(
  const sync_pb::DebugEventInfo& event_info) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (events_.size() >= kMaxEntries) {
    DVLOG(1) << "DebugInfoEventListener::AddEventToQueue Dropping an old event "
             << "because of full queue";

    events_.pop_front();
    events_dropped_ = true;
  }
  events_.push_back(event_info);
}

}  // namespace syncer
