// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.testutil;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.gerrit.server.notedb.NoteDbChangeState.PrimaryStorage;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.inject.Singleton;

/** {@link NotesMigration} with bits that can be flipped live for testing. */
@Singleton
public class TestNotesMigration extends NotesMigration {
  private volatile boolean readChanges;
  private volatile boolean writeChanges;
  private volatile PrimaryStorage changePrimaryStorage = PrimaryStorage.REVIEW_DB;
  private volatile boolean disableChangeReviewDb;
  private volatile boolean fuseUpdates;
  private volatile boolean failOnLoad;

  public TestNotesMigration() {
    resetFromEnv();
  }

  @Override
  public boolean readChanges() {
    return readChanges;
  }

  @Override
  public boolean readChangeSequence() {
    // Unlike ConfigNotesMigration, read change numbers from NoteDb by default
    // when reads are enabled, to improve test coverage.
    return readChanges;
  }

  @Override
  public PrimaryStorage changePrimaryStorage() {
    return changePrimaryStorage;
  }

  @Override
  public boolean disableChangeReviewDb() {
    return disableChangeReviewDb;
  }

  @Override
  public boolean fuseUpdates() {
    return fuseUpdates;
  }

  // Increase visbility from superclass, as tests may want to check whether
  // NoteDb data is written in specific migration scenarios.
  @Override
  public boolean rawWriteChangesSetting() {
    return writeChanges;
  }

  @Override
  public boolean failOnLoad() {
    return failOnLoad;
  }

  public TestNotesMigration setReadChanges(boolean readChanges) {
    this.readChanges = readChanges;
    return this;
  }

  public TestNotesMigration setWriteChanges(boolean writeChanges) {
    this.writeChanges = writeChanges;
    return this;
  }

  public TestNotesMigration setChangePrimaryStorage(PrimaryStorage changePrimaryStorage) {
    this.changePrimaryStorage = checkNotNull(changePrimaryStorage);
    return this;
  }

  public TestNotesMigration setDisableChangeReviewDb(boolean disableChangeReviewDb) {
    this.disableChangeReviewDb = disableChangeReviewDb;
    return this;
  }

  public TestNotesMigration setFuseUpdates(boolean fuseUpdates) {
    this.fuseUpdates = fuseUpdates;
    return this;
  }

  public TestNotesMigration setFailOnLoad(boolean failOnLoad) {
    this.failOnLoad = failOnLoad;
    return this;
  }

  public TestNotesMigration setAllEnabled(boolean enabled) {
    return setReadChanges(enabled).setWriteChanges(enabled);
  }

  public TestNotesMigration resetFromEnv() {
    return setFrom(NoteDbMode.get().migration);
  }

  @Override
  public TestNotesMigration setFrom(NotesMigration other) {
    setWriteChanges(other.rawWriteChangesSetting());
    setReadChanges(other.readChanges());
    setChangePrimaryStorage(other.changePrimaryStorage());
    setDisableChangeReviewDb(other.disableChangeReviewDb());
    setFuseUpdates(other.fuseUpdates());
    return this;
  }
}

@@ -1089,32 +1089,79 @@
 n writeChanges;%0A
+  private volatile boolean readChangeSequence;%0A
   private volati
@@ -1227,16 +1227,16 @@
 IEW_DB;%0A
-
   privat
@@ -1548,162 +1548,33 @@
     
-// Unlike ConfigNotesMigration,
+return
  read
- c
+C
 hange
- numbers from NoteDb by default%0A    // when reads are enabled, to improve test coverage.%0A    return readChanges
+Sequence
 ;%0A  
@@ -2382,32 +2382,184 @@
 turn this;%0A  %7D%0A%0A
+  public TestNotesMigration setReadChangeSequence(boolean readChangeSequence) %7B%0A    this.readChangeSequence = readChangeSequence;%0A    return this;%0A  %7D%0A%0A
   public TestNot
@@ -3477,24 +3477,24 @@
 Setting());%0A
-
     setReadC
@@ -3518,24 +3518,79 @@
 Changes());%0A
+    setReadChangeSequence(other.readChangeSequence());%0A
     setChang

Configure readChangeSequence bit explicitly