// 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.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
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 ProgressMonitor pm;
  private ProjectResource oldRsrc;

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

    oldProjectKey = project;
    newProjectKey = new Project.NameKey(NEW_PROJECT_NAME);

    pm = 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, Optional.of(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, Optional.of(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, Optional.of(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, Optional.of(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 {
    ProjectState oldProjectState = projectCache.get(oldProjectKey);
    assertThat(oldProjectState).isNotNull();

    ProjectState newProjectState = projectCache.get(newProjectKey);
    assertThat(newProjectState).isNull();

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

  private void assertRenamed(Result result) throws Exception {
    ProjectState oldProjectState = projectCache.get(oldProjectKey);
    assertThat(oldProjectState).isNull();

    ProjectState newProjectState = projectCache.get(newProjectKey);
    assertThat(newProjectState).isNotNull();

    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();
    }
  }
}
