// 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 java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.Collectors.toList;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.google.common.base.Joiner;
import com.google.gerrit.server.git.WorkQueue;
import com.google.inject.Provider;
import com.googlesource.gerrit.plugins.deleteproject.Configuration;
import com.googlesource.gerrit.plugins.deleteproject.TimeMachine;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.StreamSupport;
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 ArchiveRepositoryRemoverTest {

  private static final long ARCHIVE_DURATION = 1;
  private static final long CLEANUP_INTERVAL = TimeUnit.DAYS.toMillis(1);
  private static final int NUMBER_OF_REPOS = 10;
  private static final String PLUGIN_NAME = "delete-project";

  @Mock private ScheduledExecutorService executorMock;
  @Mock private ScheduledFuture<?> scheduledFutureMock;
  @Mock private WorkQueue workQueueMock;
  @Mock private Provider<RepositoryCleanupTask> cleanupTaskProviderMock;
  @Mock private Configuration configMock;

  @Rule public TemporaryFolder tempFolder = new TemporaryFolder();

  private ArchiveRepositoryRemover remover;
  private Path archiveRepo;

  @Before
  public void setUp() throws Exception {
    when(cleanupTaskProviderMock.get()).thenReturn(new RepositoryCleanupTask(null, null));
    when(workQueueMock.getDefaultQueue()).thenReturn(executorMock);
    doReturn(scheduledFutureMock)
        .when(executorMock)
        .scheduleAtFixedRate(
            isA(RepositoryCleanupTask.class), anyLong(), anyLong(), isA(TimeUnit.class));
    remover = new ArchiveRepositoryRemover(workQueueMock, cleanupTaskProviderMock);
    archiveRepo = tempFolder.newFolder("archive").toPath();
    when(configMock.getArchiveFolder()).thenReturn(archiveRepo);
    when(configMock.getArchiveDuration()).thenReturn(ARCHIVE_DURATION);
  }

  @Test
  public void cleanUpOverdueRepositoriesTest() throws IOException {
    setupArchiveFolder();
    try {
      TimeMachine.useFixedClockAt(
          Instant.ofEpochMilli(Files.getLastModifiedTime(archiveRepo).toMillis())
              .plusMillis(TimeUnit.DAYS.toMillis(ARCHIVE_DURATION) + 10));

      RepositoryCleanupTask task = new RepositoryCleanupTask(configMock, PLUGIN_NAME);
      task.run();
      assertThat(task.toString())
          .isEqualTo(
              String.format(
                  "[%s]: Clean up expired git repositories from the archive [%s]",
                  PLUGIN_NAME, archiveRepo));
      assertDirectoryContents(archiveRepo, true);
    } finally {
      TimeMachine.useSystemPctZoneClock();
    }
  }

  @Test
  public void testRepositoryCleanupTaskIsScheduledOnStart() {
    remover.start();
    verify(executorMock, times(1))
        .scheduleAtFixedRate(
            isA(RepositoryCleanupTask.class),
            eq(SECONDS.toMillis(1)),
            eq(CLEANUP_INTERVAL),
            eq(TimeUnit.MILLISECONDS));
  }

  @Test
  public void testRepositoryCleanupTaskIsCancelledOnStop() {
    remover.start();
    remover.stop();
    verify(scheduledFutureMock, times(1)).cancel(true);
  }

  private void setupArchiveFolder() throws IOException {
    for (int i = 0; i < NUMBER_OF_REPOS; i++) {
      createRepository("Repo_" + i);
    }
    assertDirectoryContents(archiveRepo, false);
  }

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

  private void assertDirectoryContents(Path dir, boolean expectEmpty) throws IOException {
    try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(dir)) {
      List<Path> paths = StreamSupport.stream(dirStream.spliterator(), false).collect(toList());
      if (expectEmpty && !paths.isEmpty()) {
        fail(
            String.format(
                "Expected dir [%s] to be empty but it contains: %s",
                dir, Joiner.on(", ").join(paths)));
      } else if (!expectEmpty && paths.isEmpty()) {
        fail(String.format("Expected dir [%s] to be non-empty but it is empty", dir));
      }
    }
  }
}
