// Copyright 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/engine/apply_control_data_updates.h"

#include "base/metrics/histogram.h"
#include "sync/engine/conflict_resolver.h"
#include "sync/engine/conflict_util.h"
#include "sync/engine/syncer_util.h"
#include "sync/syncable/directory.h"
#include "sync/syncable/mutable_entry.h"
#include "sync/syncable/nigori_handler.h"
#include "sync/syncable/nigori_util.h"
#include "sync/syncable/syncable_write_transaction.h"
#include "sync/util/cryptographer.h"

namespace syncer {

void ApplyControlDataUpdates(syncable::Directory* dir) {
  syncable::WriteTransaction trans(FROM_HERE, syncable::SYNCER, dir);

  std::vector<int64> handles;
  dir->GetUnappliedUpdateMetaHandles(
      &trans, ToFullModelTypeSet(ControlTypes()), &handles);

  // First, go through and manually apply any new top level datatype nodes (so
  // that we don't have to worry about hitting a CONFLICT_HIERARCHY with an
  // entry because we haven't applied its parent yet).
  // TODO(sync): if at some point we support control datatypes with actual
  // hierarchies we'll need to revisit this logic.
  ModelTypeSet control_types = ControlTypes();
  for (ModelTypeSet::Iterator iter = control_types.First(); iter.Good();
       iter.Inc()) {
    ModelType type = iter.Get();
    syncable::MutableEntry entry(&trans, syncable::GET_TYPE_ROOT, type);
    if (!entry.good())
      continue;

    if (!entry.GetIsUnappliedUpdate()) {
      // If this is a type with client generated root, the root node has been
      // created locally and might never be updated by the server. In that case
      // it has to be marked as having the initial download completed (which is
      // done by changing the root's base version to a value other than
      // CHANGES_VERSION). This does nothing if the root's base version is
      // already other than CHANGES_VERSION.
      if (IsTypeWithClientGeneratedRoot(type)) {
        dir->MarkInitialSyncEndedForType(&trans, type);
      }
      continue;
    }

    DCHECK_EQ(type, entry.GetServerModelType());
    if (type == NIGORI) {
      // Nigori node applications never fail.
      ApplyNigoriUpdate(&trans,
                        &entry,
                        dir->GetCryptographer(&trans));
    } else {
      ApplyControlUpdate(&trans,
                         &entry,
                         dir->GetCryptographer(&trans));
    }
  }

  // Go through the rest of the unapplied control updates, skipping over any
  // top level folders.
  for (std::vector<int64>::const_iterator iter = handles.begin();
       iter != handles.end(); ++iter) {
    syncable::MutableEntry entry(&trans, syncable::GET_BY_HANDLE, *iter);
    CHECK(entry.good());
    ModelType type = entry.GetServerModelType();
    CHECK(ControlTypes().Has(type));
    if (!entry.GetUniqueServerTag().empty()) {
      // We should have already applied all top level control nodes.
      DCHECK(!entry.GetIsUnappliedUpdate());
      continue;
    }

    ApplyControlUpdate(&trans,
                       &entry,
                       dir->GetCryptographer(&trans));
  }
}

// Update the nigori handler with the server's nigori node.
//
// If we have a locally modified nigori node, we merge them manually. This
// handles the case where two clients both set a different passphrase. The
// second client to attempt to commit will go into a state of having pending
// keys, unioned the set of encrypted types, and eventually re-encrypt
// everything with the passphrase of the first client and commit the set of
// merged encryption keys. Until the second client provides the pending
// passphrase, the cryptographer will preserve the encryption keys based on the
// local passphrase, while the nigori node will preserve the server encryption
// keys.
void ApplyNigoriUpdate(syncable::WriteTransaction* const trans,
                       syncable::MutableEntry* const entry,
                       Cryptographer* cryptographer) {
  DCHECK(entry->GetIsUnappliedUpdate());

  // We apply the nigori update regardless of whether there's a conflict or
  // not in order to preserve any new encrypted types or encryption keys.
  // TODO(zea): consider having this return a bool reflecting whether it was a
  // valid update or not, and in the case of invalid updates not overwrite the
  // local data.
  const sync_pb::NigoriSpecifics& nigori =
      entry->GetServerSpecifics().nigori();
  trans->directory()->GetNigoriHandler()->ApplyNigoriUpdate(nigori, trans);

  // Make sure any unsynced changes are properly encrypted as necessary.
  // We only perform this if the cryptographer is ready. If not, these are
  // re-encrypted at SetDecryptionPassphrase time (via ReEncryptEverything).
  // This logic covers the case where the nigori update marked new datatypes
  // for encryption, but didn't change the passphrase.
  if (cryptographer->is_ready()) {
    // Note that we don't bother to encrypt any data for which IS_UNSYNCED
    // == false here. The machine that turned on encryption should know about
    // and re-encrypt all synced data. It's possible it could get interrupted
    // during this process, but we currently reencrypt everything at startup
    // as well, so as soon as a client is restarted with this datatype marked
    // for encryption, all the data should be updated as necessary.

    // If this fails, something is wrong with the cryptographer, but there's
    // nothing we can do about it here.
    DVLOG(1) << "Received new nigori, encrypting unsynced changes.";
    syncable::ProcessUnsyncedChangesForEncryption(trans);
  }

  if (!entry->GetIsUnsynced()) {  // Update only.
    UpdateLocalDataFromServerData(trans, entry);
  } else {  // Conflict.
    const sync_pb::EntitySpecifics& server_specifics =
        entry->GetServerSpecifics();
    const sync_pb::NigoriSpecifics& server_nigori = server_specifics.nigori();
    const sync_pb::EntitySpecifics& local_specifics =
        entry->GetSpecifics();
    const sync_pb::NigoriSpecifics& local_nigori = local_specifics.nigori();

    // We initialize the new nigori with the server state, and will override
    // it as necessary below.
    sync_pb::EntitySpecifics new_specifics = entry->GetServerSpecifics();
    sync_pb::NigoriSpecifics* new_nigori = new_specifics.mutable_nigori();

    // If the cryptographer is not ready, another client set a new encryption
    // passphrase. If we had migrated locally, we will re-migrate when the
    // pending keys are provided. If we had set a new custom passphrase locally
    // the user will have another chance to set a custom passphrase later
    // (assuming they hadn't set a custom passphrase on the other client).
    // Therefore, we only attempt to merge the nigori nodes if the cryptographer
    // is ready.
    // Note: we only update the encryption keybag if we're sure that we aren't
    // invalidating the keystore_decryptor_token (i.e. we're either
    // not migrated or we copying over all local state).
    if (cryptographer->is_ready()) {
      if (local_nigori.has_passphrase_type() &&
          server_nigori.has_passphrase_type()) {
        // They're both migrated, preserve the local nigori if the passphrase
        // type is more conservative.
        if (server_nigori.passphrase_type() ==
                sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE &&
            local_nigori.passphrase_type() !=
                sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE) {
          DCHECK(local_nigori.passphrase_type() ==
                     sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE ||
                 local_nigori.passphrase_type() ==
                     sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
          new_nigori->CopyFrom(local_nigori);
          cryptographer->GetKeys(new_nigori->mutable_encryption_keybag());
        }
      } else if (!local_nigori.has_passphrase_type() &&
                 !server_nigori.has_passphrase_type()) {
        // Set the explicit passphrase based on the local state. If the server
        // had set an explict passphrase, we should have pending keys, so
        // should not reach this code.
        // Because neither side is migrated, we don't have to worry about the
        // keystore decryptor token.
        new_nigori->set_keybag_is_frozen(local_nigori.keybag_is_frozen());
        cryptographer->GetKeys(new_nigori->mutable_encryption_keybag());
      } else if (local_nigori.has_passphrase_type()) {
        // Local is migrated but server is not. Copy over the local migrated
        // data.
        new_nigori->CopyFrom(local_nigori);
        cryptographer->GetKeys(new_nigori->mutable_encryption_keybag());
      }  // else leave the new nigori with the server state.
    }

    // Always update to the safest set of encrypted types.
    trans->directory()->GetNigoriHandler()->UpdateNigoriFromEncryptedTypes(
        new_nigori,
        trans);

    entry->PutSpecifics(new_specifics);
    DVLOG(1) << "Resolving simple conflict, merging nigori nodes: "
             << entry;

    conflict_util::OverwriteServerChanges(entry);

    UMA_HISTOGRAM_ENUMERATION("Sync.ResolveSimpleConflict",
                              ConflictResolver::NIGORI_MERGE,
                              ConflictResolver::CONFLICT_RESOLUTION_SIZE);
  }
}

void ApplyControlUpdate(syncable::WriteTransaction* const trans,
                        syncable::MutableEntry* const entry,
                        Cryptographer* cryptographer) {
  DCHECK_NE(entry->GetServerModelType(), NIGORI);
  DCHECK(entry->GetIsUnappliedUpdate());
  if (entry->GetIsUnsynced()) {
      // We just let the server win all conflicts with control types.
    DVLOG(1) << "Ignoring local changes for control update.";
    conflict_util::IgnoreLocalChanges(entry);
    UMA_HISTOGRAM_ENUMERATION("Sync.ResolveSimpleConflict",
                              ConflictResolver::OVERWRITE_LOCAL,
                              ConflictResolver::CONFLICT_RESOLUTION_SIZE);
  }

  UpdateAttemptResponse response = AttemptToUpdateEntry(
      trans, entry, cryptographer);
  DCHECK_EQ(SUCCESS, response);
}

}  // namespace syncer
