// 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.googlesource.gerrit.plugins.renameproject.fs;

import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.renameproject.monitor.ProgressMonitor;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.Comparator;
import java.util.stream.Stream;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Singleton
public class FilesystemRenameHandler {
  private static final Logger log = LoggerFactory.getLogger(FilesystemRenameHandler.class);

  private final GitRepositoryManager repoManager;

  @Inject
  public FilesystemRenameHandler(GitRepositoryManager repoManager) {
    this.repoManager = repoManager;
  }

  public void rename(
      Project.NameKey oldProjectKey, Project.NameKey newProjectKey, ProgressMonitor pm)
      throws IOException, RepositoryNotFoundException {
    Repository repository = repoManager.openRepository(oldProjectKey);
    File repoFile = repository.getDirectory();
    RepositoryCache.close(repository);
    pm.beginTask("Renaming git repository", ProgressMonitor.UNKNOWN);
    renameGitRepository(repoFile, newProjectKey, oldProjectKey);
  }

  private void renameGitRepository(
      File source, Project.NameKey newProjectKey, Project.NameKey oldProjectKey)
      throws IOException {
    log.debug("Creating the new git repo - {}", newProjectKey.get());
    try (Repository newRepo = repoManager.createRepository(newProjectKey)) {
      File target = newRepo.getDirectory();
      RepositoryCache.close(newRepo);
      // delete the created repo, we just needed the absolute path from repo manager
      recursiveDelete(target.toPath());
      log.debug(
          "Moving the content of {} to new git repo - {}",
          oldProjectKey.get(),
          newProjectKey.get());
      Files.move(source.toPath(), target.toPath(), StandardCopyOption.ATOMIC_MOVE);
    } catch (IOException e) {
      throw new IOException("Failed to move the content to new git repo.", e);
    }
  }

  private void recursiveDelete(Path oldFile) throws IOException {
    try (Stream<Path> dir = Files.walk(oldFile, FileVisitOption.FOLLOW_LINKS)) {
      dir.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
    } catch (IOException e) {
      log.error("Failed to delete {}", oldFile.getFileName(), e);
      throw e;
    }
  }
}
