// Copyright (C) 2013 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.github.git;

import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.events.ProjectDeletedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.util.ManualRequestContext;
import com.google.gerrit.server.util.OneOffRequestContext;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.googlesource.gerrit.plugins.github.GitHubConfig;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.eclipse.jgit.api.FetchCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GitCloneStep extends ImportStep {
  private static final Logger LOG = LoggerFactory.getLogger(GitImporter.class);

  private final GitHubConfig config;
  private final File gitDir;
  private final GerritApi gerritApi;
  private final OneOffRequestContext context;
  private final String organisation;
  private final String repository;
  private final File destinationDirectory;
  private final DynamicSet<ProjectDeletedListener> deletedListeners;
  private final ProjectCache projectCache;
  private final GitRepositoryManager repoManager;

  public interface Factory {
    GitCloneStep create(
        @Assisted("organisation") String organisation, @Assisted("name") String repository);
  }

  @Inject
  public GitCloneStep(
      GitHubConfig config,
      GitHubRepository.Factory gitHubRepoFactory,
      GerritApi gerritApi,
      OneOffRequestContext context,
      DynamicSet<ProjectDeletedListener> deletedListeners,
      ProjectCache projectCache,
      GitRepositoryManager repoManager,
      @Assisted("organisation") String organisation,
      @Assisted("name") String repository)
      throws GitException {
    super(config.gitHubUrl, organisation, repository, gitHubRepoFactory);
    LOG.debug("GitHub Clone " + organisation + "/" + repository);
    this.config = config;
    this.gitDir = config.gitDir.toFile();

    this.gerritApi = gerritApi;
    this.context = context;
    this.organisation = organisation;
    this.repository = repository;
    this.destinationDirectory = prepareTargetGitDirectory(gitDir, organisation, repository);
    this.deletedListeners = deletedListeners;
    this.projectCache = projectCache;
    this.repoManager = repoManager;
  }

  private static File prepareTargetGitDirectory(File gitDir, String organisation, String repository)
      throws GitException {
    String projectName = organisation + "/" + repository;
    File repositoryDir = new File(gitDir, projectName + ".git");
    if (repositoryDir.exists()) {
      throw new GitDestinationAlreadyExistsException(projectName);
    }
    return repositoryDir;
  }

  private void createNewProject() throws GitException {
    String projectName = organisation + "/" + repository;
    try (ManualRequestContext requestContext = context.openAs(config.importAccountId)) {
      gerritApi.projects().create(projectName).get();
    } catch (ResourceConflictException e) {
      throw new GitDestinationAlreadyExistsException(projectName);
    } catch (RestApiException e) {
      throw new GitException("Unable to create repository " + projectName, e);
    }
  }

  @Override
  public void doImport(ProgressMonitor progress) throws GitException {
    createNewProject();
    String sourceUri = getSourceUri();
    try (Git git = Git.open(destinationDirectory)) {
      FetchCommand fetch = git.fetch().setRefSpecs("refs/*:refs/*").setRemote(sourceUri);
      fetch.setCredentialsProvider(getRepository().getCredentialsProvider());
      if (progress != null) {
        fetch.setProgressMonitor(progress);
      }
      LOG.info(sourceUri + "| Clone into " + destinationDirectory);
      fetch.call();
    } catch (IOException | GitAPIException e) {
      LOG.error("Unable to fetch from {} into {}", sourceUri, destinationDirectory, e);
      throw new GitCloneFailedException(sourceUri, e);
    }
  }

  private boolean isNotEmpty(File destDirectory) {
    return destDirectory.listFiles().length > 0;
  }

  @Override
  public boolean rollback() {
    File gitDirectory = destinationDirectory;
    if (!gitDirectory.exists()) {
      return false;
    }

    try {
      String projectName = organisation + "/" + repository;
      Project.NameKey key = new Project.NameKey(projectName);
      cleanJGitCache(key);
      FileUtils.deleteDirectory(gitDirectory);
      projectCache.remove(key);
      sendProjectDeletedEvent(projectName);
      return true;
    } catch (IOException e) {
      LOG.error("Cannot clean-up output Git directory " + gitDirectory);
      return false;
    }
  }

  private void cleanJGitCache(Project.NameKey key) throws IOException {
    try (Repository repository = repoManager.openRepository(key)) {
      RepositoryCache.close(repository);
    }
  }

  private void sendProjectDeletedEvent(String projectName) {
    ProjectDeletedListener.Event event =
        new ProjectDeletedListener.Event() {
          @Override
          public String getProjectName() {
            return projectName;
          }

          @Override
          public NotifyHandling getNotify() {
            return NotifyHandling.NONE;
          }
        };
    for (ProjectDeletedListener l : deletedListeners) {
      try {
        l.onProjectDeleted(event);
      } catch (RuntimeException e) {
        LOG.warn("Failure in ProjectDeletedListener", e);
      }
    }
  }
}
