// Copyright (C) 2021 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.plugins.codeowners.acceptance.testsuite;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.entities.Project.NameKey;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.registration.PrivateInternals_DynamicMapImpl;
import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersTest;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerBackend;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfig;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfigUpdate;
import com.google.gerrit.plugins.codeowners.backend.GlobMatcher;
import com.google.gerrit.plugins.codeowners.backend.PathExpressionMatcher;
import com.google.gerrit.server.IdentifiedUser;
import com.google.inject.Key;
import com.google.inject.util.Providers;
import java.nio.file.Path;
import java.util.Optional;
import javax.annotation.Nullable;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.Before;
import org.junit.Test;

/** Tests for {@link TestPathExpressions}. */
public class TestPathExpressionsTest extends AbstractCodeOwnersTest {
  private TestPathExpressions testPathExpressions;
  private DynamicMap<CodeOwnerBackend> codeOwnerBackends;

  @Before
  public void setUp() {
    testPathExpressions = plugin.getSysInjector().getInstance(TestPathExpressions.class);
    codeOwnerBackends =
        plugin.getSysInjector().getInstance(new Key<DynamicMap<CodeOwnerBackend>>() {});
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.backend", value = "find-owners")
  public void matchFileType_findOwnersBackend() throws Exception {
    assertThat(testPathExpressions.matchFileType("md")).isEqualTo("*.md");
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.backend", value = "proto")
  public void matchFileType_protoBackend() throws Exception {
    assertThat(testPathExpressions.matchFileType("md")).isEqualTo("....md");
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.backend", value = TestCodeOwnerBackend.ID)
  public void matchFileType_backendWithGlobMatcher() throws Exception {
    try (AutoCloseable registration = registerTestBackend(GlobMatcher.INSTANCE)) {
      assertThat(testPathExpressions.matchFileType("md")).isEqualTo("**.md");
    }
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.backend", value = TestCodeOwnerBackend.ID)
  public void matchFileType_backendWithUnknownMatcher() throws Exception {
    PathExpressionMatcher pathExpressionMatcher =
        new PathExpressionMatcher() {
          @Override
          public boolean matches(String pathExpression, Path relativePath) {
            return false;
          }
        };
    try (AutoCloseable registration = registerTestBackend(pathExpressionMatcher)) {
      IllegalStateException exception =
          assertThrows(IllegalStateException.class, () -> testPathExpressions.matchFileType("md"));
      assertThat(exception)
          .hasMessageThat()
          .isEqualTo(
              String.format(
                  "path expression matcher %s not supported",
                  pathExpressionMatcher.getClass().getName()));
    }
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.backend", value = TestCodeOwnerBackend.ID)
  public void matchFileType_backendWithoutMatcher() throws Exception {
    TestCodeOwnerBackend testCodeOwnerBackend =
        new TestCodeOwnerBackend(/* pathExpressionMatcher= */ null);
    try (AutoCloseable registration = registerTestBackend(testCodeOwnerBackend)) {
      IllegalStateException exception =
          assertThrows(IllegalStateException.class, () -> testPathExpressions.matchFileType("md"));
      assertThat(exception)
          .hasMessageThat()
          .isEqualTo(
              String.format(
                  "code owner backend %s doesn't support path expressions",
                  testCodeOwnerBackend.getClass().getName()));
    }
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.backend", value = "find-owners")
  public void matchAllFilesInSubfolder_findOwnersBackend() throws Exception {
    assertThat(testPathExpressions.matchAllFilesInSubfolder("foo")).isEqualTo("foo/**");
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.backend", value = "proto")
  public void matchAllFilesInSubfolder_protoBackend() throws Exception {
    assertThat(testPathExpressions.matchAllFilesInSubfolder("foo")).isEqualTo("foo/...");
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.backend", value = TestCodeOwnerBackend.ID)
  public void matchAllFilesInSubfolder_backendWithGlobMatcher() throws Exception {
    try (AutoCloseable registration = registerTestBackend(GlobMatcher.INSTANCE)) {
      assertThat(testPathExpressions.matchAllFilesInSubfolder("foo")).isEqualTo("foo/**");
    }
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.backend", value = TestCodeOwnerBackend.ID)
  public void matchAllFilesInSubfolder_backendWithUnknownMatcher() throws Exception {
    PathExpressionMatcher pathExpressionMatcher =
        new PathExpressionMatcher() {
          @Override
          public boolean matches(String pathExpression, Path relativePath) {
            return false;
          }
        };
    try (AutoCloseable registration = registerTestBackend(pathExpressionMatcher)) {
      IllegalStateException exception =
          assertThrows(
              IllegalStateException.class,
              () -> testPathExpressions.matchAllFilesInSubfolder("foo"));
      assertThat(exception)
          .hasMessageThat()
          .isEqualTo(
              String.format(
                  "path expression matcher %s not supported",
                  pathExpressionMatcher.getClass().getName()));
    }
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.backend", value = TestCodeOwnerBackend.ID)
  public void matchAllFilesInSubfolder_backendWithoutMatcher() throws Exception {
    TestCodeOwnerBackend testCodeOwnerBackend =
        new TestCodeOwnerBackend(/* pathExpressionMatcher= */ null);
    try (AutoCloseable registration = registerTestBackend(testCodeOwnerBackend)) {
      IllegalStateException exception =
          assertThrows(
              IllegalStateException.class,
              () -> testPathExpressions.matchAllFilesInSubfolder("foo"));
      assertThat(exception)
          .hasMessageThat()
          .isEqualTo(
              String.format(
                  "code owner backend %s doesn't support path expressions",
                  testCodeOwnerBackend.getClass().getName()));
    }
  }

  private AutoCloseable registerTestBackend(PathExpressionMatcher pathExpressionMatcher) {
    return registerTestBackend(new TestCodeOwnerBackend(pathExpressionMatcher));
  }

  private AutoCloseable registerTestBackend(CodeOwnerBackend codeOwnerBackend) {
    RegistrationHandle registrationHandle =
        ((PrivateInternals_DynamicMapImpl<CodeOwnerBackend>) codeOwnerBackends)
            .put("gerrit", TestCodeOwnerBackend.ID, Providers.of(codeOwnerBackend));
    return registrationHandle::remove;
  }

  private static class TestCodeOwnerBackend implements CodeOwnerBackend {
    static final String ID = "test-backend";

    @Nullable private final PathExpressionMatcher pathExpressionMatcher;

    public TestCodeOwnerBackend(@Nullable PathExpressionMatcher pathExpressionMatcher) {
      this.pathExpressionMatcher = pathExpressionMatcher;
    }

    @Override
    public boolean isCodeOwnerConfigFile(NameKey project, String fileName) {
      throw new UnsupportedOperationException();
    }

    @Override
    public Optional<CodeOwnerConfig> getCodeOwnerConfig(
        CodeOwnerConfig.Key codeOwnerConfigKey, RevWalk revWalk, ObjectId revision) {
      throw new UnsupportedOperationException();
    }

    @Override
    public Path getFilePath(CodeOwnerConfig.Key codeOwnerConfigKey) {
      throw new UnsupportedOperationException();
    }

    @Override
    public Optional<CodeOwnerConfig> upsertCodeOwnerConfig(
        CodeOwnerConfig.Key codeOwnerConfigKey,
        CodeOwnerConfigUpdate codeOwnerConfigUpdate,
        IdentifiedUser currentUser) {
      throw new UnsupportedOperationException();
    }

    @Override
    public Optional<PathExpressionMatcher> getPathExpressionMatcher() {
      return Optional.ofNullable(pathExpressionMatcher);
    }
  }
}
