// Copyright (C) 2017 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.owners.common;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static com.googlesource.gerrit.owners.common.MatcherConfig.exactMatcher;
import static com.googlesource.gerrit.owners.common.MatcherConfig.partialRegexMatcher;
import static com.googlesource.gerrit.owners.common.MatcherConfig.regexMatcher;
import static com.googlesource.gerrit.owners.common.MatcherConfig.suffixMatcher;
import static com.googlesource.gerrit.owners.common.StreamUtils.iteratorStream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.powermock.api.easymock.PowerMock.replayAll;

import com.google.gerrit.entities.Account;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(JgitWrapper.class)
public class RegexTest extends Config {

  private static final String ACCOUNT_A = "a";
  private static final String ACCOUNT_B = "b";
  private static final String ACCOUNT_C = "c";
  private static final String ACCOUNT_D = "d";
  private static final String ACCOUNT_E = "e";
  private static final String ACCOUNT_F = "f";
  private static final Account.Id ACCOUNT_A_ID = Account.id(1);
  private static final Account.Id ACCOUNT_B_ID = Account.id(2);
  private static final Account.Id ACCOUNT_C_ID = Account.id(3);
  private static final Account.Id ACCOUNT_D_ID = Account.id(4);
  private static final Account.Id ACCOUNT_E_ID = Account.id(5);
  private static final Account.Id ACCOUNT_F_ID = Account.id(6);

  @Override
  @Before
  public void setup() throws Exception {
    accounts.put(ACCOUNT_A, ACCOUNT_A_ID);
    accounts.put(ACCOUNT_B, ACCOUNT_B_ID);
    accounts.put(ACCOUNT_C, ACCOUNT_C_ID);
    accounts.put(ACCOUNT_D, ACCOUNT_D_ID);
    accounts.put(ACCOUNT_E, ACCOUNT_E_ID);
    accounts.put(ACCOUNT_F, ACCOUNT_F_ID);

    super.setup();
  }

  @Test
  public void testNewParsingYaml() throws Exception {
    replayAll();

    String fullConfig =
        createConfig(
            true,
            owners(ACCOUNT_A),
            suffixMatcher(".sql", ACCOUNT_B, ACCOUNT_C),
            regexMatcher(".*/a.*", ACCOUNT_D),
            partialRegexMatcher("Product.sql", ACCOUNT_A));
    // the function to test
    Optional<OwnersConfig> configNullable = getOwnersConfig(fullConfig);
    // check classical configuration
    assertThat(configNullable).isPresent();

    OwnersConfig config = configNullable.get();
    assertTrue(config.isInherited());

    Set<String> owners = config.getOwners();
    assertEquals(1, owners.size());
    assertTrue(owners.contains(ACCOUNT_A));
    // check matchers
    Map<String, Matcher> matchers = config.getMatchers();
    assertEquals(3, matchers.size());
    assertTrue(matchers.containsKey(".sql"));
    assertTrue(matchers.containsKey(".*/a.*"));
    assertTrue(matchers.containsKey("Product.sql"));

    // suffix .sql matcher
    Matcher advMatcher = matchers.get(".sql");
    assertEquals(2, advMatcher.getOwners().size());
    Set<Account.Id> advOwners = advMatcher.getOwners();
    assertTrue(advOwners.contains(ACCOUNT_B_ID));
    assertTrue(advOwners.contains(ACCOUNT_C_ID));

    // regex matcher
    Matcher dbMatcher = matchers.get(".*/a.*");
    assertEquals(1, dbMatcher.getOwners().size());
    Set<Account.Id> dbOwners = dbMatcher.getOwners();
    assertTrue(dbOwners.contains(ACCOUNT_D_ID));

    // partial_regex matcher
    Matcher partial = matchers.get("Product.sql");
    assertEquals(1, partial.getOwners().size());
    Set<Account.Id> partialOwners = partial.getOwners();
    assertTrue(partialOwners.contains(ACCOUNT_A_ID));
  }

  @Test
  public void checkMatchers() throws Exception {
    String parentConfig =
        createConfig(
            true,
            owners(ACCOUNT_A),
            suffixMatcher(".sql", ACCOUNT_B, ACCOUNT_C),
            regexMatcher(".*/a.*", ACCOUNT_D));
    String childConfig =
        createConfig(
            true,
            owners(ACCOUNT_F),
            exactMatcher("project/file.txt", ACCOUNT_D, ACCOUNT_E),
            partialRegexMatcher("alfa", ACCOUNT_A));

    expectConfig("OWNERS", parentConfig);
    expectConfig("project/OWNERS", childConfig);

    creatingPatchList(
        Arrays.asList(
            "project/file.txt", // matches exact in
            // project owners d,e
            "file1.txt", // no matches so nothing for this
            "project/afile2.sql", // matches two matchers so we have b,c,d
            "project/bfile.txt", // no matching
            "projectalfa", // matches PartialRegex
            "project/file.sql")); // only .sql matching b,c
    replayAll();

    // function under test
    PathOwners owners = new PathOwners(accounts, repository, branch, patchList);

    // assertions on classic owners
    Set<Account.Id> ownersSet = owners.get().get("project/OWNERS");
    assertEquals(2, ownersSet.size());

    // get matchers
    Map<String, Matcher> matchers = owners.getMatchers();
    assertEquals(4, matchers.size());

    // asserts we have 1 exact matcher
    List<Entry<String, Matcher>> onlyExacts =
        iteratorStream(matchers.entrySet().iterator())
            .filter(entry -> entry.getValue() instanceof ExactMatcher)
            .collect(Collectors.toList());
    assertEquals(1, onlyExacts.size());
    assertEquals("project/file.txt", onlyExacts.get(0).getKey());

    // ... 1 regex matcher
    List<Entry<String, Matcher>> regexList =
        StreamUtils.iteratorStream(matchers.entrySet().iterator())
            .filter(entry -> entry.getValue() instanceof RegExMatcher)
            .collect(Collectors.toList());
    assertEquals(1, regexList.size());
    assertEquals(".*/a.*", regexList.get(0).getKey());

    // ... 1 partial regex matcher
    List<Entry<String, Matcher>> partialRegexList =
        iteratorStream(matchers.entrySet().iterator())
            .filter(entry -> entry.getValue() instanceof PartialRegExMatcher)
            .collect(Collectors.toList());
    assertEquals(1, partialRegexList.size());
    assertEquals("alfa", partialRegexList.get(0).getKey());

    // .... 1 suffix matcher
    List<Entry<String, Matcher>> suffixList =
        iteratorStream(matchers.entrySet().iterator())
            .filter(entry -> entry.getValue() instanceof SuffixMatcher)
            .collect(Collectors.toList());
    assertEquals(1, suffixList.size());
    assertEquals(".sql", suffixList.get(0).getKey());

    // now checks file owners as well
    Map<String, Set<Account.Id>> fileOwners = owners.getFileOwners();
    assertEquals(6, fileOwners.size());

    Set<Account.Id> set1 = fileOwners.get("project/file.txt");
    assertEquals(4, set1.size()); // includes classic owners a and f
    assertTrue(set1.contains(ACCOUNT_A_ID));
    assertTrue(set1.contains(ACCOUNT_D_ID));
    assertTrue(set1.contains(ACCOUNT_E_ID));
    assertTrue(set1.contains(ACCOUNT_F_ID));

    Set<Account.Id> set2 = fileOwners.get("project/afile2.sql");
    assertEquals(5, set2.size());
    assertTrue(set2.contains(ACCOUNT_A_ID));
    assertTrue(set2.contains(ACCOUNT_B_ID));
    assertTrue(set2.contains(ACCOUNT_C_ID));
    assertTrue(set2.contains(ACCOUNT_D_ID));
    assertTrue(set2.contains(ACCOUNT_F_ID));

    Set<Account.Id> set3 = fileOwners.get("project/file.sql");
    assertEquals(4, set3.size());
    assertTrue(set3.contains(ACCOUNT_A_ID));
    assertTrue(set3.contains(ACCOUNT_B_ID));
    assertTrue(set3.contains(ACCOUNT_C_ID));
    assertTrue(set3.contains(ACCOUNT_F_ID));

    Set<Account.Id> set4 = fileOwners.get("projectalfa");
    assertEquals(1, set4.size()); // only 1 because a is class and alfa owner
    assertTrue(set4.contains(ACCOUNT_A_ID));
  }

  @Test
  public void testMatchersOnlyConfig() throws Exception {
    replayAll();

    Optional<OwnersConfig> ownersConfigOpt =
        getOwnersConfig(createConfig(false, new String[0], suffixMatcher(".txt", ACCOUNT_B)));

    assertThat(ownersConfigOpt).isPresent();
    OwnersConfig ownersConfig = ownersConfigOpt.get();

    assertThat(ownersConfig.getOwners()).isEmpty();
    assertThat(ownersConfig.getMatchers()).isNotEmpty();
  }

  @Test
  public void testkRegexShouldMatchOnlyOnSuffix() throws Exception {
    String configString = createConfig(false, new String[0], suffixMatcher(".sql", ACCOUNT_B));

    expectConfig("OWNERS", configString);
    expectNoConfig("project/OWNERS");
    creatingPatch("project/file.sql", "another.txt");
    replayAll();

    PathOwners owners = new PathOwners(accounts, repository, branch, patchList);

    Set<String> ownedFiles = owners.getFileOwners().keySet();
    assertThat(ownedFiles).containsExactly("project/file.sql");
  }
}
