// 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 "components/sync/engine_impl/apply_control_data_updates.h"

#include <stdint.h>

#include <vector>

#include "base/metrics/histogram_macros.h"
#include "components/sync/base/cryptographer.h"
#include "components/sync/engine_impl/conflict_resolver.h"
#include "components/sync/engine_impl/conflict_util.h"
#include "components/sync/engine_impl/syncer_util.h"
#include "components/sync/syncable/directory.h"
#include "components/sync/syncable/mutable_entry.h"
#include "components/sync/syncable/nigori_handler.h"
#include "components/sync/syncable/nigori_util.h"
#include "components/sync/syncable/syncable_write_transaction.h"

namespace syncer {

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

  std::vector<int64_t> 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 (ModelType type : control_types) {
    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_t>::const_iterator iter = handles.begin();
       iter != handles.end(); ++iter) {
    syncable::MutableEntry entry(&trans, syncable::GET_BY_HANDLE, *iter);
    DCHECK(entry.good());
    ModelType type = entry.GetServerModelType();
    DCHECK(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
