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

import static com.google.common.truth.Truth.assertThat;
import static com.googlesource.gerrit.plugins.uploadvalidator.DuplicatePathnameValidator.conflict;
import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.EMPTY_CONTENT;
import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.EMPTY_PLUGIN_CONFIG;
import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.createDirCacheEntry;
import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.createEmptyDirCacheEntries;
import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.makeCommit;
import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.transformMessage;
import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.transformMessages;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gerrit.server.git.validators.CommitValidationMessage;

import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.Set;

public class DuplicatePathnameValidatorTest extends ValidatorTestCase {
  private static final ImmutableList<String> INITIAL_PATHNAMES =
      ImmutableList.of(
          "a" , "ab",
          "f1/a", "f1/ab",
          "f2/a", "f2/ab", "f2/sF1/a", "f2/sF1/ab");

  private final List<String> vistedPaths = Lists.newArrayList();
  private final List<CommitValidationMessage> messages = Lists.newArrayList();

  private TestRepository<Repository> testRepo;
  private Set<String> changedPaths;
  private DuplicatePathnameValidator validator;

  private void runCheck(List<String> existingTreePaths, Set<String> testPaths,
    List<CommitValidationMessage> messages, List<String> visitedPaths)
        throws Exception {
    RevCommit c = makeCommit(
        testRepo.getRevWalk(), createEmptyDirCacheEntries(existingTreePaths, testRepo), testRepo);
    try (TreeWalk tw = new TreeWalk(repo)) {
      tw.setRecursive(false);
      tw.addTree(c.getTree());
      tw.setFilter(new ListVisitedPathsFilter(visitedPaths));
      validator.checkForDuplicatesAgainstTheWholeTree(tw, testPaths, messages);
    }
  }

  @Override
  @Before
  public void init() throws IOException {
    super.init();
    testRepo = new TestRepository<>(repo);
    validator = new DuplicatePathnameValidator(null, null, null, null);
    validator.setLocale(Locale.ENGLISH);
  }

  @Test
  public void testSkipSubTreesWithImproperPrefix() throws Exception {
    changedPaths = Sets.newHashSet("f1/A");
    runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths);
    assertThat(transformMessages(messages))
        .containsExactly(transformMessage(conflict("f1/A", "f1/a")));
    assertThat(vistedPaths).containsExactly(
        "a", "ab", "f1", "f1/a", "f1/ab", "f2");
  }

  @Test
  public void testFindConflictingSubtree() throws Exception {
    changedPaths = Sets.newHashSet("F1/a");
    runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths);
    assertThat(transformMessages(messages))
        .containsExactly(transformMessage(conflict("F1", "f1")));
    assertThat(vistedPaths).containsExactly("a", "ab", "f1", "f2");
  }

  @Test
  public void testFindConflictingSubtree2() throws Exception {
    changedPaths = Sets.newHashSet("f2/sf1", "F1/a");
    runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths);
    assertThat(transformMessages(messages)).containsExactly(
        transformMessage(conflict("F1", "f1")),
        transformMessage(conflict("f2/sf1", "f2/sF1")));
    assertThat(vistedPaths).containsExactly(
        "a", "ab", "f1", "f2", "f2/a", "f2/ab", "f2/sF1");
  }

  @Test
  public void testFindDuplicates() throws Exception {
    changedPaths = Sets.newHashSet("AB", "f1/A", "f2/Ab");
    runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths);
    assertThat(transformMessages(messages)).containsExactly(
        transformMessage(conflict("AB", "ab")),
        transformMessage(conflict("f1/A", "f1/a")),
        transformMessage(conflict("f2/Ab", "f2/ab")));
    assertThat(vistedPaths).containsExactly(
        "a", "ab", "f1", "f1/a", "f1/ab", "f2", "f2/a", "f2/ab", "f2/sF1");
  }

  @Test
  public void testFindNoDuplicates() throws Exception {
    changedPaths = Sets.newHashSet("a", "ab", "f1/ab");
    runCheck(INITIAL_PATHNAMES, changedPaths, messages, vistedPaths);
    assertThat(messages).isEmpty();
    assertThat(vistedPaths).containsExactly(
        "a", "ab", "f1", "f1/a", "f1/ab", "f2");
  }

  @Test
  public void testCheckInsideOfCommit() throws Exception {
    List<String> filenames = Lists.newArrayList(INITIAL_PATHNAMES);
    // add files with conflicting pathnames
    filenames.add("A");
    filenames.add("F1/ab");
    filenames.add("f2/sF1/aB");
    try (RevWalk rw = new RevWalk(repo)) {
      RevCommit c =
          makeCommit(rw, createEmptyDirCacheEntries(filenames, testRepo), testRepo);
      List<CommitValidationMessage> m = validator.performValidation(repo, c, rw);
      assertThat(m).hasSize(4);
      // During checking inside of the commit it's unknown which file is checked
      // first, because of that, both capabilities must be checked.
      assertThat(transformMessages(m)).containsAnyOf(
          transformMessage(conflict("A", "a")),
          transformMessage(conflict("a", "A")));

      assertThat(transformMessages(m)).containsAnyOf(
          transformMessage(conflict("F1", "f1")),
          transformMessage(conflict("f1", "F1")));

      assertThat(transformMessages(m)).containsAnyOf(
          transformMessage(conflict("F1/ab", "f1/ab")),
          transformMessage(conflict("f1/ab", "F1/ab")));

      assertThat(transformMessages(m)).containsAnyOf(
          transformMessage(
              conflict("f2/sF1/aB", "f2/sF1/ab")),
          transformMessage(
              conflict("f2/sF1/ab", "f2/sF1/aB")));
    }
  }

  @Test
  public void testCheckRenaming() throws Exception {
    try (RevWalk rw = new RevWalk(repo)) {
      RevCommit c = makeCommit(
          rw, createEmptyDirCacheEntries(INITIAL_PATHNAMES, testRepo), testRepo);
      DirCacheEntry[] entries = new DirCacheEntry[INITIAL_PATHNAMES.size()];
      for (int x = 0; x < INITIAL_PATHNAMES.size(); x++) {
        // Rename files
        entries[x] = createDirCacheEntry(INITIAL_PATHNAMES.get(x).toUpperCase(),
            EMPTY_CONTENT, testRepo);
      }
      RevCommit c1 = makeCommit(rw, entries, testRepo, c);
      List<CommitValidationMessage> m = validator.performValidation(repo, c1, rw);
      assertThat(m).isEmpty();
    }
  }

  @Test
  public void validatorInactiveWhenConfigEmpty() {
    assertThat(DuplicatePathnameValidator.isActive(EMPTY_PLUGIN_CONFIG))
        .isFalse();
  }

  @Test
  public void defaultLocale() {
    assertThat(DuplicatePathnameValidator.getLocale(EMPTY_PLUGIN_CONFIG))
        .isEqualTo(Locale.ENGLISH);
  }

  @Test
  public void testGetParentFolder() {
    assertThat(validator.allParentFolders(INITIAL_PATHNAMES))
        .containsExactlyElementsIn(
            ImmutableList.of("f1", "f2", "f2/sF1"));
  }
}
