// Copyright (C) 2018 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.server.schema;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.server.schema.NoteDbSchemaUpdater.requiredUpgrades;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.notedb.IntBlob;
import com.google.gerrit.server.notedb.RepoSequence;
import com.google.gerrit.server.notedb.Sequences;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import com.google.gerrit.testing.TestUpdateUI;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;
import org.junit.Test;

public class NoteDbSchemaUpdaterTest {
  @Test
  public void requiredUpgradesFromNoVersion() throws Exception {
    assertThat(requiredUpgrades(0, versions(10))).containsExactly(10).inOrder();
    assertThat(requiredUpgrades(0, versions(10, 11, 12))).containsExactly(10, 11, 12).inOrder();
  }

  @Test
  public void requiredUpgradesFromExistingVersion() throws Exception {
    ImmutableSortedSet<Integer> versions = versions(10, 11, 12, 13);
    assertThat(requiredUpgrades(10, versions)).containsExactly(11, 12, 13).inOrder();
    assertThat(requiredUpgrades(11, versions)).containsExactly(12, 13).inOrder();
    assertThat(requiredUpgrades(12, versions)).containsExactly(13).inOrder();
    assertThat(requiredUpgrades(13, versions)).isEmpty();
  }

  @Test
  public void downgradeNotSupported() throws Exception {
    StorageException thrown =
        assertThrows(StorageException.class, () -> requiredUpgrades(14, versions(10, 11, 12, 13)));
    assertThat(thrown)
        .hasMessageThat()
        .contains("Cannot downgrade NoteDb schema from version 14 to 13");
  }

  @Test
  public void skipToFirstVersionNotSupported() throws Exception {
    ImmutableSortedSet<Integer> versions = versions(10, 11, 12);
    assertThat(requiredUpgrades(9, versions)).containsExactly(10, 11, 12).inOrder();
    StorageException thrown =
        assertThrows(StorageException.class, () -> requiredUpgrades(8, versions));
    assertThat(thrown).hasMessageThat().contains("Cannot skip NoteDb schema from version 8 to 10");
  }

  private static class TestUpdate {
    protected final Config cfg;
    protected final AllProjectsName allProjectsName;
    protected final AllUsersName allUsersName;
    protected final NoteDbSchemaUpdater updater;
    protected final GitRepositoryManager repoManager;
    protected final NoteDbSchemaVersion.Arguments args;
    private final List<String> messages;

    TestUpdate(Optional<Integer> initialVersion) {
      cfg = new Config();
      allProjectsName = new AllProjectsName("The-Projects");
      allUsersName = new AllUsersName("The-Users");
      repoManager = new InMemoryRepositoryManager();

      args = new NoteDbSchemaVersion.Arguments(repoManager, allProjectsName, allUsersName);
      NoteDbSchemaVersionManager versionManager =
          new NoteDbSchemaVersionManager(allProjectsName, repoManager);
      updater =
          new NoteDbSchemaUpdater(
              cfg,
              allUsersName,
              repoManager,
              new TestSchemaCreator(initialVersion),
              versionManager,
              args,
              ImmutableSortedMap.of(10, TestSchema_10.class, 11, TestSchema_11.class));
      messages = new ArrayList<>();
    }

    private class TestSchemaCreator implements SchemaCreator {
      private final Optional<Integer> initialVersion;

      TestSchemaCreator(Optional<Integer> initialVersion) {
        this.initialVersion = initialVersion;
      }

      @Override
      public void create() throws IOException {
        try (Repository repo = repoManager.createRepository(allProjectsName);
            TestRepository<Repository> tr = new TestRepository<>(repo)) {
          if (initialVersion.isPresent()) {
            tr.update(RefNames.REFS_VERSION, tr.blob(initialVersion.get().toString()));
          }
        } catch (Exception e) {
          throw new StorageException(e);
        }
        repoManager.createRepository(allUsersName).close();
        setUp();
      }

      @Override
      public void ensureCreated() throws IOException {
        try {
          repoManager.openRepository(allProjectsName).close();
        } catch (RepositoryNotFoundException e) {
          create();
        }
      }
    }

    protected void setNotesMigrationConfig() {
      cfg.setString("noteDb", "changes", "write", "true");
      cfg.setString("noteDb", "changes", "read", "true");
      cfg.setString("noteDb", "changes", "primaryStorage", "NOTE_DB");
      cfg.setString("noteDb", "changes", "disableReviewDb", "true");
    }

    protected void seedGroupSequenceRef() {
      new RepoSequence(
              repoManager,
              GitReferenceUpdated.DISABLED,
              allUsersName,
              Sequences.NAME_GROUPS,
              () -> 1,
              1)
          .next();
    }

    /** Test-specific setup. */
    protected void setUp() {}

    ImmutableList<String> update() throws Exception {
      updater.update(
          new TestUpdateUI() {
            @Override
            public void message(String m) {
              messages.add(m);
            }
          });
      return getMessages();
    }

    ImmutableList<String> getMessages() {
      return ImmutableList.copyOf(messages);
    }

    Optional<Integer> readVersion() throws Exception {
      try (Repository repo = repoManager.openRepository(allProjectsName)) {
        return IntBlob.parse(repo, RefNames.REFS_VERSION).map(IntBlob::value);
      }
    }

    static class TestSchema_10 implements NoteDbSchemaVersion {
      @Override
      public void upgrade(Arguments args, UpdateUI ui) {
        ui.message("body of 10");
      }
    }

    static class TestSchema_11 implements NoteDbSchemaVersion {
      @Override
      public void upgrade(Arguments args, UpdateUI ui) {
        ui.message("BODY OF 11");
      }
    }
  }

  @Test
  public void bootstrapUpdateWith216Prerequisites() throws Exception {
    TestUpdate u =
        new TestUpdate(Optional.empty()) {
          @Override
          public void setUp() {
            setNotesMigrationConfig();
            seedGroupSequenceRef();
          }
        };
    assertThat(u.update())
        .containsExactly(
            "Migrating data to schema 10 ...",
            "body of 10",
            "Migrating data to schema 11 ...",
            "BODY OF 11")
        .inOrder();
    assertThat(u.readVersion()).hasValue(11);
  }

  @Test
  public void bootstrapUpdateFailsWithoutNotesMigrationConfig() throws Exception {
    TestUpdate u =
        new TestUpdate(Optional.empty()) {
          @Override
          public void setUp() {
            seedGroupSequenceRef();
          }
        };
    StorageException thrown = assertThrows(StorageException.class, () -> u.update());
    assertThat(thrown).hasMessageThat().contains("NoteDb change migration was not completed");
    assertThat(u.getMessages()).isEmpty();
    assertThat(u.readVersion()).isEmpty();
  }

  @Test
  public void bootstrapUpdateFailsWithoutGroupSequenceRef() throws Exception {
    TestUpdate u =
        new TestUpdate(Optional.empty()) {
          @Override
          public void setUp() {
            setNotesMigrationConfig();
          }
        };
    StorageException thrown = assertThrows(StorageException.class, () -> u.update());
    assertThat(thrown).hasMessageThat().contains("upgrade to 2.16.x first");
    assertThat(u.getMessages()).isEmpty();
    assertThat(u.readVersion()).isEmpty();
  }

  @Test
  public void updateTwoVersions() throws Exception {
    TestUpdate u = new TestUpdate(Optional.of(9));
    assertThat(u.update())
        .containsExactly(
            "Migrating data to schema 10 ...",
            "body of 10",
            "Migrating data to schema 11 ...",
            "BODY OF 11")
        .inOrder();
    assertThat(u.readVersion()).hasValue(11);
  }

  @Test
  public void updateOneVersion() throws Exception {
    TestUpdate u = new TestUpdate(Optional.of(10));
    assertThat(u.update())
        .containsExactly("Migrating data to schema 11 ...", "BODY OF 11")
        .inOrder();
    assertThat(u.readVersion()).hasValue(11);
  }

  @Test
  public void updateNoOp() throws Exception {
    // This test covers the state when running the updater after initializing a new 3.x site, which
    // seeds the schema version ref with the latest version.
    TestUpdate u = new TestUpdate(Optional.of(11));
    assertThat(u.update()).isEmpty();
    assertThat(u.readVersion()).hasValue(11);
  }

  private static ImmutableSortedSet<Integer> versions(Integer... versions) {
    return ImmutableSortedSet.copyOf(versions);
  }
}
