// 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.google.gerrit.server.index.change;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.server.index.change.StalenessChecker.refsAreStale;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toList;

import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.ListMultimap;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Project;
import com.google.gerrit.index.RefState;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.change.StalenessChecker.RefStatePattern;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import java.util.stream.Stream;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.junit.Before;
import org.junit.Test;

public class StalenessCheckerTest {
  private static final String SHA1 = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
  private static final String SHA2 = "badc0feebadc0feebadc0feebadc0feebadc0fee";

  private static final Project.NameKey P1 = Project.nameKey("project1");
  private static final Project.NameKey P2 = Project.nameKey("project2");

  private static final Change.Id C = Change.id(1234);

  private GitRepositoryManager repoManager;
  private Repository r1;
  private Repository r2;
  private TestRepository<Repository> tr1;
  private TestRepository<Repository> tr2;

  @Before
  public void setUp() throws Exception {
    repoManager = new InMemoryRepositoryManager();
    r1 = repoManager.createRepository(P1);
    tr1 = new TestRepository<>(r1);
    r2 = repoManager.createRepository(P2);
    tr2 = new TestRepository<>(r2);
  }

  @Test
  public void parseStates() {
    assertInvalidState(null);
    assertInvalidState("");
    assertInvalidState("project1:refs/heads/foo");
    assertInvalidState("project1:refs/heads/foo:notasha");
    assertInvalidState("project1:refs/heads/foo:");

    assertThat(
            RefState.parseStates(
                byteArrays(
                    P1 + ":refs/heads/foo:" + SHA1,
                    P1 + ":refs/heads/bar:" + SHA2,
                    P2 + ":refs/heads/baz:" + SHA1)))
        .isEqualTo(
            ImmutableSetMultimap.of(
                P1, RefState.create("refs/heads/foo", SHA1),
                P1, RefState.create("refs/heads/bar", SHA2),
                P2, RefState.create("refs/heads/baz", SHA1)));
  }

  private static void assertInvalidState(String state) {
    assertThrows(IllegalArgumentException.class, () -> RefState.parseStates(byteArrays(state)));
  }

  @Test
  public void refStateToByteArray() {
    assertThat(
            new String(
                RefState.create("refs/heads/foo", ObjectId.fromString(SHA1)).toByteArray(P1),
                UTF_8))
        .isEqualTo(P1 + ":refs/heads/foo:" + SHA1);
    assertThat(
            new String(RefState.create("refs/heads/foo", (ObjectId) null).toByteArray(P1), UTF_8))
        .isEqualTo(P1 + ":refs/heads/foo:" + ObjectId.zeroId().name());
  }

  @Test
  public void parsePatterns() {
    assertInvalidPattern(null);
    assertInvalidPattern("");
    assertInvalidPattern("project:");
    assertInvalidPattern("project:refs/heads/foo");
    assertInvalidPattern("project:refs/he*ds/bar");
    assertInvalidPattern("project:refs/(he)*ds/bar");
    assertInvalidPattern("project:invalidrefname");

    ListMultimap<Project.NameKey, RefStatePattern> r =
        StalenessChecker.parsePatterns(
            byteArrays(
                P1 + ":refs/heads/*",
                P2 + ":refs/heads/foo/*/bar",
                P2 + ":refs/heads/foo/*-baz/*/quux"));

    assertThat(r.keySet()).containsExactly(P1, P2);
    RefStatePattern p = r.get(P1).get(0);
    assertThat(p.pattern()).isEqualTo("refs/heads/*");
    assertThat(p.prefix()).isEqualTo("refs/heads/");
    assertThat(p.regex().pattern()).isEqualTo("^\\Qrefs/heads/\\E.*\\Q\\E$");
    assertThat(p.match("refs/heads/foo")).isTrue();
    assertThat(p.match("xrefs/heads/foo")).isFalse();
    assertThat(p.match("refs/tags/foo")).isFalse();

    p = r.get(P2).get(0);
    assertThat(p.pattern()).isEqualTo("refs/heads/foo/*/bar");
    assertThat(p.prefix()).isEqualTo("refs/heads/foo/");
    assertThat(p.regex().pattern()).isEqualTo("^\\Qrefs/heads/foo/\\E.*\\Q/bar\\E$");
    assertThat(p.match("refs/heads/foo//bar")).isTrue();
    assertThat(p.match("refs/heads/foo/x/bar")).isTrue();
    assertThat(p.match("refs/heads/foo/x/y/bar")).isTrue();
    assertThat(p.match("refs/heads/foo/x/baz")).isFalse();

    p = r.get(P2).get(1);
    assertThat(p.pattern()).isEqualTo("refs/heads/foo/*-baz/*/quux");
    assertThat(p.prefix()).isEqualTo("refs/heads/foo/");
    assertThat(p.regex().pattern()).isEqualTo("^\\Qrefs/heads/foo/\\E.*\\Q-baz/\\E.*\\Q/quux\\E$");
    assertThat(p.match("refs/heads/foo/-baz//quux")).isTrue();
    assertThat(p.match("refs/heads/foo/x-baz/x/quux")).isTrue();
    assertThat(p.match("refs/heads/foo/x/y-baz/x/y/quux")).isTrue();
    assertThat(p.match("refs/heads/foo/x-baz/x/y")).isFalse();
  }

  @Test
  public void refStatePatternToByteArray() {
    assertThat(new String(RefStatePattern.create("refs/*").toByteArray(P1), UTF_8))
        .isEqualTo(P1 + ":refs/*");
  }

  private static void assertInvalidPattern(String state) {
    assertThrows(
        IllegalArgumentException.class, () -> StalenessChecker.parsePatterns(byteArrays(state)));
  }

  @Test
  public void isStaleRefStatesOnly() throws Exception {
    String ref1 = "refs/heads/foo";
    ObjectId id1 = tr1.update(ref1, tr1.commit().message("commit 1"));
    String ref2 = "refs/heads/bar";
    ObjectId id2 = tr2.update(ref2, tr2.commit().message("commit 2"));

    // Not stale.
    assertThat(
            refsAreStale(
                    repoManager,
                    C,
                    ImmutableSetMultimap.of(
                        P1, RefState.create(ref1, id1.name()),
                        P2, RefState.create(ref2, id2.name())),
                    ImmutableListMultimap.of())
                .isStale())
        .isFalse();

    // Wrong ref value.
    assertThat(
            refsAreStale(
                    repoManager,
                    C,
                    ImmutableSetMultimap.of(
                        P1, RefState.create(ref1, SHA1),
                        P2, RefState.create(ref2, id2.name())),
                    ImmutableListMultimap.of())
                .isStale())
        .isTrue();

    // Swapped repos.
    assertThat(
            refsAreStale(
                    repoManager,
                    C,
                    ImmutableSetMultimap.of(
                        P1, RefState.create(ref1, id2.name()),
                        P2, RefState.create(ref2, id1.name())),
                    ImmutableListMultimap.of())
                .isStale())
        .isTrue();

    // Two refs in same repo, not stale.
    String ref3 = "refs/heads/baz";
    ObjectId id3 = tr1.update(ref3, tr1.commit().message("commit 3"));
    tr1.update(ref3, id3);
    assertThat(
            refsAreStale(
                    repoManager,
                    C,
                    ImmutableSetMultimap.of(
                        P1, RefState.create(ref1, id1.name()),
                        P1, RefState.create(ref3, id3.name())),
                    ImmutableListMultimap.of())
                .isStale())
        .isFalse();

    // Ignore ref not mentioned.
    assertThat(
            refsAreStale(
                    repoManager,
                    C,
                    ImmutableSetMultimap.of(P1, RefState.create(ref1, id1.name())),
                    ImmutableListMultimap.of())
                .isStale())
        .isFalse();

    // One ref wrong.
    assertThat(
            refsAreStale(
                    repoManager,
                    C,
                    ImmutableSetMultimap.of(
                        P1, RefState.create(ref1, id1.name()),
                        P1, RefState.create(ref3, SHA1)),
                    ImmutableListMultimap.of())
                .isStale())
        .isTrue();
  }

  @Test
  public void isStaleWithRefStatePatterns() throws Exception {
    String ref1 = "refs/heads/foo";
    ObjectId id1 = tr1.update(ref1, tr1.commit().message("commit 1"));

    // ref1 is only ref matching pattern.
    assertThat(
            refsAreStale(
                    repoManager,
                    C,
                    ImmutableSetMultimap.of(P1, RefState.create(ref1, id1.name())),
                    ImmutableListMultimap.of(P1, RefStatePattern.create("refs/heads/*")))
                .isStale())
        .isFalse();

    // Now ref2 matches pattern, so stale unless ref2 is present in state map.
    String ref2 = "refs/heads/bar";
    ObjectId id2 = tr1.update(ref2, tr1.commit().message("commit 2"));
    assertThat(
            refsAreStale(
                    repoManager,
                    C,
                    ImmutableSetMultimap.of(P1, RefState.create(ref1, id1.name())),
                    ImmutableListMultimap.of(P1, RefStatePattern.create("refs/heads/*")))
                .isStale())
        .isTrue();
    assertThat(
            refsAreStale(
                    repoManager,
                    C,
                    ImmutableSetMultimap.of(
                        P1, RefState.create(ref1, id1.name()),
                        P1, RefState.create(ref2, id2.name())),
                    ImmutableListMultimap.of(P1, RefStatePattern.create("refs/heads/*")))
                .isStale())
        .isFalse();
  }

  @Test
  public void isStaleWithNonPrefixPattern() throws Exception {
    String ref1 = "refs/heads/foo";
    ObjectId id1 = tr1.update(ref1, tr1.commit().message("commit 1"));
    tr1.update("refs/heads/bar", tr1.commit().message("commit 2"));

    // ref1 is only ref matching pattern.
    assertThat(
            refsAreStale(
                    repoManager,
                    C,
                    ImmutableSetMultimap.of(P1, RefState.create(ref1, id1.name())),
                    ImmutableListMultimap.of(P1, RefStatePattern.create("refs/*/foo")))
                .isStale())
        .isFalse();

    // Now ref2 matches pattern, so stale unless ref2 is present in state map.
    String ref3 = "refs/other/foo";
    ObjectId id3 = tr1.update(ref3, tr1.commit().message("commit 3"));
    assertThat(
            refsAreStale(
                    repoManager,
                    C,
                    ImmutableSetMultimap.of(P1, RefState.create(ref1, id1.name())),
                    ImmutableListMultimap.of(P1, RefStatePattern.create("refs/*/foo")))
                .isStale())
        .isTrue();
    assertThat(
            refsAreStale(
                    repoManager,
                    C,
                    ImmutableSetMultimap.of(
                        P1, RefState.create(ref1, id1.name()),
                        P1, RefState.create(ref3, id3.name())),
                    ImmutableListMultimap.of(P1, RefStatePattern.create("refs/*/foo")))
                .isStale())
        .isFalse();
  }

  private static Iterable<byte[]> byteArrays(String... strs) {
    return Stream.of(strs).map(s -> s != null ? s.getBytes(UTF_8) : null).collect(toList());
  }
}
