// 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 com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Change.Id;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.renameproject.RenameProject.Step;
import com.googlesource.gerrit.plugins.renameproject.cache.CacheRenameHandler;
import com.googlesource.gerrit.plugins.renameproject.database.DatabaseRenameHandler;
import com.googlesource.gerrit.plugins.renameproject.database.IndexUpdateHandler;
import com.googlesource.gerrit.plugins.renameproject.fs.FilesystemRenameHandler;
import com.googlesource.gerrit.plugins.renameproject.monitor.ProgressMonitor;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RevertRenameProject {
  private static final Logger log = LoggerFactory.getLogger(RevertRenameProject.class);

  private final DatabaseRenameHandler dbHandler;
  private final FilesystemRenameHandler fsHandler;
  private final CacheRenameHandler cacheHandler;
  private final IndexUpdateHandler indexHandler;

  @Inject
  RevertRenameProject(
      DatabaseRenameHandler dbHandler,
      FilesystemRenameHandler fsHandler,
      CacheRenameHandler cacheHandler,
      IndexUpdateHandler indexHandler) {
    this.dbHandler = dbHandler;
    this.fsHandler = fsHandler;
    this.cacheHandler = cacheHandler;
    this.indexHandler = indexHandler;
  }

  void performRevert(
      List<Step> stepsPerformed,
      List<Id> changeIds,
      Project.NameKey oldProjectKey,
      Project.NameKey newProjectKey,
      ProgressMonitor pm)
      throws IOException, OrmException {
    pm.beginTask("Reverting the rename procedure.");
    List<Change.Id> updatedChangeIds = Collections.emptyList();
    if (stepsPerformed.contains(Step.FILESYSTEM)) {
      try {
        fsHandler.rename(newProjectKey, oldProjectKey, pm);
        log.debug("Reverted the git repo name to {} successfully.", oldProjectKey.get());
      } catch (IOException e) {
        log.error(
            "Failed to revert git repo name. Aborting revert. Exception caught: {}", e.toString());
        throw e;
      }
    }
    if (stepsPerformed.contains(Step.CACHE)) {
      cacheHandler.update(newProjectKey, oldProjectKey);
      log.debug("Successfully removed project {} from project cache.", newProjectKey.get());
    }
    if (stepsPerformed.contains(Step.DATABASE)) {
      try {
        updatedChangeIds = dbHandler.rename(changeIds, newProjectKey, oldProjectKey, pm);
        log.debug(
            "Reverted the changes in DB successfully from project {} to project {}.",
            newProjectKey.get(),
            oldProjectKey.get());
      } catch (OrmException e) {
        log.error(
            "Failed to revert changes in DB for project {}. Secondary indexes not reverted. Exception caught: {}",
            oldProjectKey.get(),
            e.toString());
        throw e;
      }
    }
    if (stepsPerformed.contains(Step.INDEX)) {
      try {
        indexHandler.updateIndex(updatedChangeIds, oldProjectKey, pm);
        log.debug(
            "Reverted the secondary index successfully from project {} to project {}.",
            newProjectKey.get(),
            oldProjectKey.get());
      } catch (InterruptedException e) {
        log.error(
            "Secondary index revert failed for {}. Exception caught: {}",
            oldProjectKey.get(),
            e.toString());
      }
    }
  }
}
