// Copyright 2022 The Bazel Authors. All rights reserved.
//
// 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.devtools.build.lib.authandtls.credentialhelper;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static org.junit.Assert.assertThrows;

import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.vfs.DigestHashFunction;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
import java.io.OutputStream;
import java.net.URI;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link CredentialHelperProvider}. */
@RunWith(JUnit4.class)
public class CredentialHelperProviderTest {
  private static final PathFragment DEFAULT_HELPER_PATH =
      PathFragment.create("/path/to/default/helper");
  private static final PathFragment EXAMPLE_COM_HELPER_PATH =
      PathFragment.create("/path/to/example/com/helper");
  private static final PathFragment EXAMPLE_COM_WILDCARD_HELPER_PATH =
      PathFragment.create("/path/to/example/com/wildcard/helper");
  private static final PathFragment SUB_EXAMPLE_COM_WILDCARD_HELPER_PATH =
      PathFragment.create("/path/to/sub/example/com/wildcard/helper");

  private final FileSystem fileSystem = new InMemoryFileSystem(DigestHashFunction.SHA256);

  @Before
  public void setUp() throws Exception {
    setUpHelper(fileSystem.getPath(DEFAULT_HELPER_PATH));
    setUpHelper(fileSystem.getPath(EXAMPLE_COM_HELPER_PATH));
    setUpHelper(fileSystem.getPath(EXAMPLE_COM_WILDCARD_HELPER_PATH));
    setUpHelper(fileSystem.getPath(SUB_EXAMPLE_COM_WILDCARD_HELPER_PATH));
  }

  private void setUpHelper(Path path) throws Exception {
    Preconditions.checkNotNull(path);

    path.getParentDirectory().createDirectoryAndParents();
    try (OutputStream stream = path.getOutputStream()) {
      // Just create an empty file, nothing to do.
    }
    path.setExecutable(true);
  }

  @Test
  public void noHelpersConfigured() {
    CredentialHelperProvider provider = CredentialHelperProvider.builder().build();

    assertThat(provider.findCredentialHelper(URI.create("http://example.com/foo"))).isEmpty();
    assertThat(provider.findCredentialHelper(URI.create("https://example.com/foo"))).isEmpty();
    assertThat(provider.findCredentialHelper(URI.create("grpc://example.com/foo"))).isEmpty();
    assertThat(provider.findCredentialHelper(URI.create("grpcs://example.com/foo"))).isEmpty();
    assertThat(provider.findCredentialHelper(URI.create("custom://example.com/foo"))).isEmpty();

    assertThat(provider.findCredentialHelper(URI.create("https://subdomain.example.com/bar")))
        .isEmpty();
    assertThat(provider.findCredentialHelper(URI.create("https://other-domain.com"))).isEmpty();
  }

  private void assertInvalidPattern(String pattern) {
    Preconditions.checkNotNull(pattern);

    IllegalArgumentException exception =
        assertThrows(
            IllegalArgumentException.class,
            () ->
                CredentialHelperProvider.builder()
                    .add(pattern, fileSystem.getPath(DEFAULT_HELPER_PATH)));
    assertThat(exception).hasMessageThat().contains(pattern);
  }

  @Test
  public void invalidPattern() throws Exception {
    assertInvalidPattern("foo.*.example.com");
    assertInvalidPattern("*.foo.*.example.com");
    assertInvalidPattern("*-foo.example.com");
    assertInvalidPattern("example.*");
    assertInvalidPattern("*.example.*");

    // Punycode
    assertInvalidPattern("foo.*.münchen.de");
    assertInvalidPattern(".*.münchen.de");
    assertInvalidPattern("foo-*.münchen.de");
  }

  @Test
  public void addNonExecutableDefaultHelper() throws Exception {
    Path helper = fileSystem.getPath("/path/to/non/executable");
    setUpHelper(helper);
    helper.setExecutable(false);
    CredentialHelperProvider.Builder provider = CredentialHelperProvider.builder();

    IllegalArgumentException exception =
        assertThrows(IllegalArgumentException.class, () -> provider.add(helper));
    assertThat(exception).hasMessageThat().contains("is not executable");
  }

  @Test
  public void onlyDefaultHelper() throws Exception {
    Path helper = fileSystem.getPath(DEFAULT_HELPER_PATH);
    CredentialHelperProvider provider = CredentialHelperProvider.builder().add(helper).build();

    assertThat(provider.findCredentialHelper(URI.create("http://example.com/foo")).get().getPath())
        .isEqualTo(helper);
    assertThat(provider.findCredentialHelper(URI.create("https://example.com/foo")).get().getPath())
        .isEqualTo(helper);
    assertThat(provider.findCredentialHelper(URI.create("grpc://example.com/foo")).get().getPath())
        .isEqualTo(helper);
    assertThat(provider.findCredentialHelper(URI.create("grpcs://example.com/foo")).get().getPath())
        .isEqualTo(helper);
    assertThat(
            provider.findCredentialHelper(URI.create("custom://example.com/foo")).get().getPath())
        .isEqualTo(helper);

    assertThat(
            provider
                .findCredentialHelper(URI.create("https://subdomain.example.com/bar"))
                .get()
                .getPath())
        .isEqualTo(helper);
    assertThat(
            provider.findCredentialHelper(URI.create("https://other-domain.com")).get().getPath())
        .isEqualTo(helper);
  }

  @Test
  public void withHostHelpersAndDefaultFallback() throws Exception {
    Path defaultHelper = fileSystem.getPath(DEFAULT_HELPER_PATH);
    Path exampleComHelper = fileSystem.getPath(EXAMPLE_COM_HELPER_PATH);
    CredentialHelperProvider provider =
        CredentialHelperProvider.builder()
            .add(defaultHelper)
            .add("example.com", exampleComHelper)
            .build();

    assertThat(provider.findCredentialHelper(URI.create("http://example.com/foo")).get().getPath())
        .isEqualTo(exampleComHelper);
    assertThat(provider.findCredentialHelper(URI.create("https://example.com/foo")).get().getPath())
        .isEqualTo(exampleComHelper);
    assertThat(provider.findCredentialHelper(URI.create("grpc://example.com/foo")).get().getPath())
        .isEqualTo(exampleComHelper);
    assertThat(provider.findCredentialHelper(URI.create("grpcs://example.com/foo")).get().getPath())
        .isEqualTo(exampleComHelper);
    assertThat(
            provider.findCredentialHelper(URI.create("custom://example.com/foo")).get().getPath())
        .isEqualTo(exampleComHelper);

    assertThat(
            provider
                .findCredentialHelper(URI.create("https://subdomain.example.com/bar"))
                .get()
                .getPath())
        .isEqualTo(defaultHelper);
    assertThat(
            provider.findCredentialHelper(URI.create("https://other-domain.com")).get().getPath())
        .isEqualTo(defaultHelper);
  }

  @Test
  public void wildcardMatching() throws Exception {
    Path defaultHelper = fileSystem.getPath(DEFAULT_HELPER_PATH);
    Path exampleComWildcardHelper = fileSystem.getPath(EXAMPLE_COM_WILDCARD_HELPER_PATH);
    CredentialHelperProvider provider =
        CredentialHelperProvider.builder()
            .add(defaultHelper)
            .add("*.example.com", exampleComWildcardHelper)
            .build();

    assertThat(provider.findCredentialHelper(URI.create("http://example.com/foo")).get().getPath())
        .isEqualTo(exampleComWildcardHelper);
    assertThat(provider.findCredentialHelper(URI.create("https://example.com/foo")).get().getPath())
        .isEqualTo(exampleComWildcardHelper);
    assertThat(provider.findCredentialHelper(URI.create("grpc://example.com/foo")).get().getPath())
        .isEqualTo(exampleComWildcardHelper);
    assertThat(provider.findCredentialHelper(URI.create("grpcs://example.com/foo")).get().getPath())
        .isEqualTo(exampleComWildcardHelper);
    assertThat(
            provider.findCredentialHelper(URI.create("custom://example.com/foo")).get().getPath())
        .isEqualTo(exampleComWildcardHelper);

    assertThat(
            provider
                .findCredentialHelper(URI.create("https://subdomain.example.com/bar"))
                .get()
                .getPath())
        .isEqualTo(exampleComWildcardHelper);
    assertThat(
            provider
                .findCredentialHelper(URI.create("https://subdomain2.example.com/bar"))
                .get()
                .getPath())
        .isEqualTo(exampleComWildcardHelper);
    assertThat(
            provider
                .findCredentialHelper(URI.create("https://sub.subdomain.example.com/bar"))
                .get()
                .getPath())
        .isEqualTo(exampleComWildcardHelper);
    assertThat(
            provider
                .findCredentialHelper(URI.create("https://subdomain.example.com/bar"))
                .get()
                .getPath())
        .isEqualTo(exampleComWildcardHelper);

    assertThat(
            provider.findCredentialHelper(URI.create("https://other-domain.com")).get().getPath())
        .isEqualTo(defaultHelper);
  }

  @Test
  public void preferExactMatchOverWildcardMatching() throws Exception {
    Path defaultHelper = fileSystem.getPath(DEFAULT_HELPER_PATH);
    Path exampleComHelper = fileSystem.getPath(EXAMPLE_COM_HELPER_PATH);
    Path exampleComWildcardHelper = fileSystem.getPath(EXAMPLE_COM_WILDCARD_HELPER_PATH);
    CredentialHelperProvider provider =
        CredentialHelperProvider.builder()
            .add(defaultHelper)
            .add("example.com", exampleComHelper)
            .add("*.example.com", exampleComWildcardHelper)
            .build();

    assertThat(provider.findCredentialHelper(URI.create("http://example.com/foo")).get().getPath())
        .isEqualTo(exampleComHelper);
    assertThat(provider.findCredentialHelper(URI.create("https://example.com/foo")).get().getPath())
        .isEqualTo(exampleComHelper);
    assertThat(provider.findCredentialHelper(URI.create("grpc://example.com/foo")).get().getPath())
        .isEqualTo(exampleComHelper);
    assertThat(provider.findCredentialHelper(URI.create("grpcs://example.com/foo")).get().getPath())
        .isEqualTo(exampleComHelper);
    assertThat(
            provider.findCredentialHelper(URI.create("custom://example.com/foo")).get().getPath())
        .isEqualTo(exampleComHelper);

    assertThat(
            provider
                .findCredentialHelper(URI.create("https://subdomain.example.com/bar"))
                .get()
                .getPath())
        .isEqualTo(exampleComWildcardHelper);
    assertThat(
            provider
                .findCredentialHelper(URI.create("https://subdomain2.example.com/bar"))
                .get()
                .getPath())
        .isEqualTo(exampleComWildcardHelper);
    assertThat(
            provider
                .findCredentialHelper(URI.create("https://sub.subdomain.example.com/bar"))
                .get()
                .getPath())
        .isEqualTo(exampleComWildcardHelper);
    assertThat(
            provider
                .findCredentialHelper(URI.create("https://subdomain.example.com/bar"))
                .get()
                .getPath())
        .isEqualTo(exampleComWildcardHelper);

    assertThat(
            provider.findCredentialHelper(URI.create("https://other-domain.com")).get().getPath())
        .isEqualTo(defaultHelper);
  }

  @Test
  public void preferMostSpecificWildcardMatch() throws Exception {
    Path exampleComWildcardHelper = fileSystem.getPath(EXAMPLE_COM_WILDCARD_HELPER_PATH);
    Path subExampleComWildcardHelper = fileSystem.getPath(SUB_EXAMPLE_COM_WILDCARD_HELPER_PATH);
    CredentialHelperProvider provider =
        CredentialHelperProvider.builder()
            .add("*.example.com", exampleComWildcardHelper)
            .add("*.sub.example.com", subExampleComWildcardHelper)
            .build();

    assertThat(provider.findCredentialHelper(URI.create("https://example.com/bar")).get().getPath())
        .isEqualTo(exampleComWildcardHelper);
    assertThat(
            provider
                .findCredentialHelper(URI.create("https://foo.example.com/bar"))
                .get()
                .getPath())
        .isEqualTo(exampleComWildcardHelper);
    assertThat(
            provider
                .findCredentialHelper(URI.create("https://sub.example.com/bar"))
                .get()
                .getPath())
        .isEqualTo(subExampleComWildcardHelper);
    assertThat(
            provider
                .findCredentialHelper(URI.create("https://foo.sub.example.com/bar"))
                .get()
                .getPath())
        .isEqualTo(subExampleComWildcardHelper);
  }

  @Test
  public void punycodeMatching() throws Exception {
    Path defaultHelper = fileSystem.getPath(DEFAULT_HELPER_PATH);
    Path specificHelper = fileSystem.getPath(EXAMPLE_COM_HELPER_PATH);
    Path subdomainHelper = fileSystem.getPath(EXAMPLE_COM_HELPER_PATH);

    CredentialHelperProvider provider =
        CredentialHelperProvider.builder()
            .add(defaultHelper)
            .add("münchen.de", specificHelper)
            .add("*.köln.de", subdomainHelper)
            .build();

    // münchen.de
    assertThat(
            provider.findCredentialHelper(URI.create("http://xn--mnchen-3ya.de")).get().getPath())
        .isEqualTo(specificHelper);
    assertThat(
            provider
                .findCredentialHelper(URI.create("http://foo.xn--mnchen-3ya.de"))
                .get()
                .getPath())
        .isEqualTo(defaultHelper);
    assertThat(provider.findCredentialHelper(URI.create("http://muenchen.de")).get().getPath())
        .isEqualTo(defaultHelper);

    // köln.de
    assertThat(provider.findCredentialHelper(URI.create("http://xn--kln-sna.de")).get().getPath())
        .isEqualTo(subdomainHelper);
    assertThat(
            provider.findCredentialHelper(URI.create("http://foo.xn--kln-sna.de")).get().getPath())
        .isEqualTo(subdomainHelper);
    assertThat(
            provider.findCredentialHelper(URI.create("http://bar.xn--kln-sna.de")).get().getPath())
        .isEqualTo(subdomainHelper);
    assertThat(provider.findCredentialHelper(URI.create("http://koeln.de")).get().getPath())
        .isEqualTo(defaultHelper);

    // småland.se
    assertThat(
            provider.findCredentialHelper(URI.create("http://xn--smland-jua.se")).get().getPath())
        .isEqualTo(defaultHelper);
  }

  @Test
  public void parentDomain() {
    assertThat(CredentialHelperProvider.parentDomain("com")).isEmpty();

    assertThat(CredentialHelperProvider.parentDomain("foo.example.com")).hasValue("example.com");
    assertThat(CredentialHelperProvider.parentDomain("example.com")).hasValue("com");

    // Punycode URIs (münchen.de).
    assertThat(CredentialHelperProvider.parentDomain("foo.xn--mnchen-3ya.de"))
        .hasValue("xn--mnchen-3ya.de");
    assertThat(CredentialHelperProvider.parentDomain("bar.foo.xn--mnchen-3ya.de"))
        .hasValue("foo.xn--mnchen-3ya.de");
    assertThat(CredentialHelperProvider.parentDomain("xn--mnchen-3ya.de")).hasValue("de");
  }
}
