// Copyright (C) 2016 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.ericsson.gerrit.plugins.gcconductor;

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

import com.ericsson.gerrit.plugins.gcconductor.evaluator.EvaluatorConfig;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ResetCommand.ResetType;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
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 EvaluationTaskTest {

  @Rule public TemporaryFolder dir = new TemporaryFolder();

  private static final String SOME_HOSTNAME = "hostname";

  @Mock private EvaluatorConfig cfg;
  @Mock private GcQueue queue;

  private EvaluationTask task;
  private Repository repository;
  private String repositoryPath;

  @Before
  public void setUp() throws Exception {
    repository = createRepository("someRepo.git");
    repositoryPath = repository.getDirectory().getAbsolutePath();
    task = new EvaluationTask(cfg, queue, SOME_HOSTNAME, repositoryPath);
  }

  @Test
  public void dirtyRepositoryObjectsShouldBeAddedToTheQueue() throws Exception {
    when(cfg.getPackedThreshold()).thenReturn(1);
    addFileTo(repository);
    when(queue.contains(repositoryPath)).thenReturn(false);
    task = new EvaluationTask(cfg, queue, SOME_HOSTNAME, repositoryPath);
    task.run();
    verify(queue).add(repositoryPath, SOME_HOSTNAME, false);
  }

  @Test
  public void dirtyRepositoryPacksShouldBeAddedToTheQueue() throws Exception {
    when(cfg.getPackedThreshold()).thenReturn(1);
    when(queue.contains(repositoryPath)).thenReturn(false);
    addFileTo(repository);
    gc(repository);
    task = new EvaluationTask(cfg, queue, SOME_HOSTNAME, repositoryPath);
    task.run();
    verify(queue).add(repositoryPath, SOME_HOSTNAME, false);
  }

  @Test
  public void repositoryShouldNotBeAddedIfAlreadyInQueue() throws Exception {
    when(queue.contains(repositoryPath)).thenReturn(true);
    task.run();
    verify(queue, never()).add(repositoryPath, SOME_HOSTNAME, false);
  }

  @Test
  public void cleanRepositoryShouldNotBeAddedToQueue() throws Exception {
    when(cfg.getLooseThreshold()).thenReturn(1);
    when(cfg.getPackedThreshold()).thenReturn(1);
    when(queue.contains(repositoryPath)).thenReturn(false);
    task.run();
    verify(queue, never()).add(repositoryPath, SOME_HOSTNAME, false);
  }

  @Test
  public void queueThrowsErrorCheckingIfRepositoryExists() throws Exception {
    doThrow(new GcQueueException("some message", new Throwable()))
        .when(queue)
        .contains(repositoryPath);
    task.run();
    verify(queue, never()).add(repositoryPath, SOME_HOSTNAME, false);
  }

  @Test
  public void queueThrowsErrorInsertingRepository() throws Exception {
    when(queue.contains(repositoryPath)).thenReturn(false);
    doThrow(new GcQueueException("some message", new Throwable()))
        .when(queue)
        .add(repositoryPath, SOME_HOSTNAME, false);
    task.run();
  }

  @Test
  public void repositoryNoLongerExist() throws Exception {
    when(queue.contains(repositoryPath)).thenReturn(false);
    dir.delete();
    task.run();
    verify(queue, never()).add(repositoryPath, SOME_HOSTNAME, true);
  }

  @Test
  public void toStringReturnsProperMessage() {
    assertThat(task.toString()).isEqualTo("Evaluate if repository need GC: " + repositoryPath);
  }

  @Test
  public void noUnreferencedObjects() throws Exception {
    addFileTo(repository);
    FileRepository fileRepository = (FileRepository) repository;
    assertThat(task.getUnreferencedLooseObjectsCount(fileRepository)).isEqualTo(0);
  }

  @Test
  public void unreferencedObjectsCountShouldBeOne() throws Exception {
    try (Git git = new Git(repository)) {
      RevCommit initialCommit = git.commit().setMessage("initial commit").call();
      addFileTo(repository);
      git.reset().setMode(ResetType.HARD).setRef(initialCommit.getName()).call();
    }
    FileRepository fileRepository = (FileRepository) repository;
    removeReflog(fileRepository.getDirectory());
    assertThat(task.getUnreferencedLooseObjectsCount(fileRepository)).isEqualTo(1);
  }

  private void removeReflog(File directory) throws IOException {
    Path logs = directory.toPath().resolve("logs");
    Files.walk(logs).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
  }

  private Repository createRepository(String repoName) throws Exception {
    File repo = dir.newFolder(repoName);
    try (Git git = Git.init().setDirectory(repo).call()) {
      return git.getRepository();
    }
  }

  private void addFileTo(Repository repository) throws Exception {
    try (Git git = new Git(repository)) {
      new File(repository.getDirectory().getParent(), "test");
      git.add().addFilepattern("test").call();
      git.commit().setMessage("Add test file").call();
    }
  }

  private void gc(Repository repository) throws Exception {
    try (Git git = new Git(repository)) {
      git.gc().setAggressive(true).call();
    }
  }
}
