// 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.deleteproject.fs;

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

import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.events.ProjectDeletedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.googlesource.gerrit.plugins.deleteproject.Configuration;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.util.stream.Stream;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Repository;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class FilesystemDeleteHandlerTest {

  @Mock private GitRepositoryManager repoManager;
  @Mock private ProjectDeletedListener projectDeleteListener;
  @Mock private Configuration config;

  @Rule public TemporaryFolder tempFolder = new TemporaryFolder();

  private DynamicSet<ProjectDeletedListener> deletedListener;
  private FilesystemDeleteHandler fsDeleteHandler;
  private Path basePath;

  @Before
  public void setUp() throws Exception {
    basePath = tempFolder.newFolder().toPath().resolve("base");
    deletedListener = new DynamicSet<>();
    deletedListener.add("", projectDeleteListener);
  }

  @Test
  public void shouldDeleteRepository() throws Exception {
    String repoName = "testRepo";
    Repository repository = createRepository(repoName);
    Project.NameKey nameKey = Project.nameKey(repoName);
    when(repoManager.openRepository(nameKey)).thenReturn(repository);
    when(config.shouldArchiveDeletedRepos()).thenReturn(false);
    fsDeleteHandler = new FilesystemDeleteHandler(repoManager, deletedListener, config);
    fsDeleteHandler.delete(nameKey, false);
    assertThat(repository.getDirectory().exists()).isFalse();
  }

  @Test
  public void shouldDeleteEmptyParentFolders() throws Exception {
    String repoName = "a/b/c";
    Repository repository = createRepository(repoName);
    Project.NameKey nameKey = Project.nameKey(repoName);
    when(repoManager.openRepository(nameKey)).thenReturn(repository);
    fsDeleteHandler = new FilesystemDeleteHandler(repoManager, deletedListener, config);
    fsDeleteHandler.delete(nameKey, false);
    assertThat(repository.getDirectory().exists()).isFalse();
  }

  @Test
  public void shouldKeepCommonFolders() throws Exception {
    String repoToDeleteName = "a/b/c/d";
    Repository repoToDelete = createRepository(repoToDeleteName);

    String repoToKeepName = "a/b/e";
    Repository repoToKeep = createRepository(repoToKeepName);

    Project.NameKey nameKey = Project.nameKey(repoToDeleteName);
    when(repoManager.openRepository(nameKey)).thenReturn(repoToDelete);
    fsDeleteHandler = new FilesystemDeleteHandler(repoManager, deletedListener, config);
    fsDeleteHandler.delete(nameKey, false);
    assertThat(repoToDelete.getDirectory().exists()).isFalse();
    assertThat(repoToKeep.getDirectory().exists()).isTrue();
  }

  @Test
  public void shouldPreserveRepository() throws Exception {
    String repoName = "preservedRepo";
    Repository repository = createRepository(repoName);
    Project.NameKey nameKey = Project.nameKey(repoName);
    when(repoManager.openRepository(nameKey)).thenReturn(repository);
    fsDeleteHandler = new FilesystemDeleteHandler(repoManager, deletedListener, config);
    fsDeleteHandler.delete(nameKey, true);
    assertThat(repository.getDirectory().exists()).isTrue();
  }

  private FileRepository createRepository(String repoName) throws IOException {
    Path repoPath = Files.createDirectories(basePath.resolve(repoName));
    Repository repository = new FileRepository(repoPath.toFile());
    repository.create(true);
    return (FileRepository) repository;
  }

  @Test
  public void archiveRepository() throws Exception {
    String repoName = "parent_project/p3";
    Repository repository = createRepository(repoName);
    Path archiveFolder = basePath.resolve("test_archive");
    when(config.shouldArchiveDeletedRepos()).thenReturn(true);
    when(config.getArchiveFolder()).thenReturn(archiveFolder);
    Project.NameKey nameKey = Project.nameKey(repoName);
    when(repoManager.openRepository(nameKey)).thenReturn(repository);
    fsDeleteHandler = new FilesystemDeleteHandler(repoManager, deletedListener, config);
    fsDeleteHandler.delete(nameKey, false);
    assertThat(repository.getDirectory().exists()).isFalse();
    String patternToVerify = archiveFolder.resolve(repoName).toString() + "*%archived%.git";
    assertThat(pathExistsWithPattern(archiveFolder, patternToVerify)).isTrue();
  }

  private boolean pathExistsWithPattern(Path archiveFolder, String patternToVerify)
      throws IOException {
    PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + patternToVerify);
    try (Stream<Path> stream = Files.walk(archiveFolder)) {
      return stream.anyMatch(matcher::matches);
    }
  }
}
