// Copyright (C) 2019 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.googlesource.gerrit.plugins.renameproject;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;

import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit.Result;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.acceptance.UseLocalDisk;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.server.project.ProjectResource;
import com.google.gerrit.server.project.ProjectState;
import com.googlesource.gerrit.plugins.renameproject.RenameProject.Step;
import com.googlesource.gerrit.plugins.renameproject.monitor.ProgressMonitor;
import java.util.List;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;

@TestPlugin(
    name = "rename-project",
    sysModule = "com.googlesource.gerrit.plugins.renameproject.Module",
    sshModule = "com.googlesource.gerrit.plugins.renameproject.SshModule")
public class RevertRenameProjectTest extends LightweightPluginDaemonTest {
  private static final String NEW_PROJECT_NAME = "newProject";

  private RenameProject renameProject;
  private RevertRenameProject revertRenameProject;
  private Project.NameKey oldProjectKey;
  private Project.NameKey newProjectKey;
  private Optional<ProgressMonitor> pm;
  private ProjectResource oldRsrc;

  @Before
  public void init() {
    renameProject = plugin.getSysInjector().getInstance(RenameProject.class);
    revertRenameProject = plugin.getSysInjector().getInstance(RevertRenameProject.class);

    oldProjectKey = project;
    newProjectKey = Project.nameKey(NEW_PROJECT_NAME);

    pm = Optional.of(Mockito.mock(ProgressMonitor.class));

    oldRsrc = Mockito.mock(ProjectResource.class);
    when(oldRsrc.getNameKey()).thenReturn(oldProjectKey);
  }

  @Test
  @UseLocalDisk
  public void testRevertFromFsHandler() throws Exception {
    Result result = createChange();
    List<Change.Id> changeIds = renameProject.getChanges(oldRsrc, pm);

    renameProject.fsRenameStep(oldProjectKey, newProjectKey, pm);
    assertRenamed(result);

    revertRenameProject.performRevert(
        renameProject.getStepsPerformed(), changeIds, oldProjectKey, newProjectKey, pm);
    assertReverted();
  }

  @Test
  @UseLocalDisk
  public void testRevertFromCacheHandler() throws Exception {
    Result result = createChange();
    List<Change.Id> changeIds = renameProject.getChanges(oldRsrc, pm);

    renameProject.fsRenameStep(oldProjectKey, newProjectKey, pm);
    renameProject.cacheRenameStep(oldProjectKey, newProjectKey);
    assertRenamed(result);

    revertRenameProject.performRevert(
        renameProject.getStepsPerformed(), changeIds, oldProjectKey, newProjectKey, pm);
    assertReverted();
  }

  @Test
  @UseLocalDisk
  public void testRevertFromDbHandler() throws Exception {
    Result result = createChange();
    List<Change.Id> changeIds = renameProject.getChanges(oldRsrc, pm);

    renameProject.fsRenameStep(oldProjectKey, newProjectKey, pm);
    renameProject.cacheRenameStep(oldProjectKey, newProjectKey);
    renameProject.dbRenameStep(changeIds, oldProjectKey, newProjectKey, pm);
    assertRenamed(result);

    revertRenameProject.performRevert(
        renameProject.getStepsPerformed(), changeIds, oldProjectKey, newProjectKey, pm);
    assertReverted();
  }

  @Test
  @UseLocalDisk
  public void testRevertFromIndexHandler() throws Exception {
    Result result = createChange();
    List<Change.Id> changeIds = renameProject.getChanges(oldRsrc, pm);

    renameProject.fsRenameStep(oldProjectKey, newProjectKey, pm);
    renameProject.cacheRenameStep(oldProjectKey, newProjectKey);
    renameProject.dbRenameStep(changeIds, oldProjectKey, newProjectKey, pm);
    renameProject.indexRenameStep(changeIds, oldProjectKey, newProjectKey, pm);
    assertRenamed(result);

    revertRenameProject.performRevert(
        renameProject.getStepsPerformed(), changeIds, oldProjectKey, newProjectKey, pm);
    assertReverted();
  }

  private void assertReverted() throws Exception {
    Optional<ProjectState> oldProjectState = projectCache.get(oldProjectKey);
    assertThat(oldProjectState.isPresent()).isTrue();

    Optional<ProjectState> newProjectState = projectCache.get(newProjectKey);
    assertThat(newProjectState.isPresent()).isFalse();

    assertThat(queryProvider.get().byProject(oldProjectKey)).isNotEmpty();
    assertThat(queryProvider.get().byProject(newProjectKey)).isEmpty();
  }

  private void assertRenamed(Result result) throws Exception {
    Optional<ProjectState> oldProjectState = projectCache.get(oldProjectKey);
    assertThat(oldProjectState.isPresent()).isFalse();

    Optional<ProjectState> newProjectState = projectCache.get(newProjectKey);
    assertThat(newProjectState.isPresent()).isTrue();

    if (renameProject.getStepsPerformed().contains(Step.DATABASE)) {
      ChangeApi changeApi = gApi.changes().id(NEW_PROJECT_NAME, result.getChange().getId().get());
      ChangeInfo changeInfo = changeApi.info();
      assertThat(changeInfo.changeId).isEqualTo(result.getChangeId());
    }

    if (renameProject.getStepsPerformed().contains(Step.INDEX)) {
      assertThat(queryProvider.get().byProject(oldProjectKey)).isEmpty();
    }
  }
}
