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

#include "sync/syncable/directory.h"
#include "sync/syncable/mutable_entry.h"
#include "sync/syncable/syncable_write_transaction.h"

namespace syncer {

//////////////////////////////////////////////////////////////////////////
// WriteTransaction member definitions
WriteTransaction::WriteTransaction(const tracked_objects::Location& from_here,
                                   UserShare* share)
    : BaseTransaction(share),
      transaction_(NULL) {
  transaction_ = new syncable::WriteTransaction(from_here, syncable::SYNCAPI,
                                                share->directory.get());
}

WriteTransaction::WriteTransaction(const tracked_objects::Location& from_here,
                                   UserShare* share,
                                   int64* new_model_version)
    : BaseTransaction(share),
      transaction_(NULL) {
  transaction_ = new syncable::WriteTransaction(from_here,
                                                share->directory.get(),
                                                new_model_version);
}

WriteTransaction::~WriteTransaction() {
  delete transaction_;
}

syncable::BaseTransaction* WriteTransaction::GetWrappedTrans() const {
  return transaction_;
}

void WriteTransaction::SetDataTypeContext(
    ModelType type,
    syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status,
    const std::string& context) {
  DCHECK(ProtocolTypes().Has(type));
  int field_number = GetSpecificsFieldNumberFromModelType(type);
  sync_pb::DataTypeContext local_context;
  GetDirectory()->GetDataTypeContext(transaction_,
                                     type,
                                     &local_context);
  if (local_context.context() == context)
    return;

  if (!local_context.has_data_type_id())
    local_context.set_data_type_id(field_number);

  DCHECK_EQ(field_number, local_context.data_type_id());
  DCHECK_GE(local_context.version(), 0);
  local_context.set_version(local_context.version() + 1);
  local_context.set_context(context);
  GetDirectory()->SetDataTypeContext(transaction_,
                                     type,
                                     local_context);
  if (refresh_status == syncer::SyncChangeProcessor::REFRESH_NEEDED) {
    DVLOG(1) << "Forcing refresh of type " << ModelTypeToString(type);
    // Clear the progress token from the progress markers. Preserve all other
    // state, in case a GC directive was present.
    sync_pb::DataTypeProgressMarker progress_marker;
    GetDirectory()->GetDownloadProgress(type, &progress_marker);
    progress_marker.clear_token();
    GetDirectory()->SetDownloadProgress(type, progress_marker);

    // Go through and reset the versions for all the synced entities of this
    // data type.
    GetDirectory()->ResetVersionsForType(transaction_, type);
  }

  // Note that it's possible for a GetUpdatesResponse that arrives immediately
  // after the context update to override the cleared progress markers.
  // TODO(zea): add a flag in the directory to prevent this from happening.
  // See crbug.com/360280
}

void WriteTransaction::UpdateEntriesMarkAttachmentAsOnServer(
    const AttachmentId& attachment_id) {
  syncable::Directory::Metahandles handles;
  GetDirectory()->GetMetahandlesByAttachmentId(
      transaction_, attachment_id.GetProto(), &handles);
  for (syncable::Directory::Metahandles::iterator iter = handles.begin();
       iter != handles.end();
       ++iter) {
    syncable::MutableEntry entry(transaction_, syncable::GET_BY_HANDLE, *iter);
    entry.MarkAttachmentAsOnServer(attachment_id.GetProto());
  }
}

}  // namespace syncer
