// Copyright 2023 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.remote;

import static com.google.common.truth.Truth.assertThat;

import com.google.devtools.build.lib.actions.ActionInputHelper;
import com.google.devtools.build.lib.actions.Spawn;
import com.google.devtools.build.lib.actions.cache.VirtualActionInput;
import com.google.devtools.build.lib.exec.util.SpawnBuilder;
import com.google.devtools.build.lib.remote.RemoteScrubbing.Config;
import com.google.devtools.build.lib.remote.Scrubber.SpawnScrubber;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link Scrubber}. */
@RunWith(JUnit4.class)
public class ScrubberTest {

  @Test
  public void noScrubbing() {
    var scrubber = new Scrubber(Config.getDefaultInstance());

    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Foo"))).isNull();
  }

  @Test
  public void matchExactMnemonic() {
    var scrubber =
        new Scrubber(
            Config.newBuilder()
                .addRules(
                    Config.Rule.newBuilder()
                        .setMatcher(Config.Matcher.newBuilder().setMnemonic("Foo")))
                .build());

    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Foo"))).isNotNull();
    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Foobar"))).isNull();
  }

  @Test
  public void matchUnionMnemonic() {
    var scrubber =
        new Scrubber(
            Config.newBuilder()
                .addRules(
                    Config.Rule.newBuilder()
                        .setMatcher(Config.Matcher.newBuilder().setMnemonic("Foo|Bar")))
                .build());

    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Foo"))).isNotNull();
    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Bar"))).isNotNull();
    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Baz"))).isNull();
  }

  @Test
  public void matchWildcardMnemonic() {
    var scrubber =
        new Scrubber(
            Config.newBuilder()
                .addRules(
                    Config.Rule.newBuilder()
                        .setMatcher(Config.Matcher.newBuilder().setMnemonic("Foo.*")))
                .build());

    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Foo"))).isNotNull();
    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Foobar"))).isNotNull();
    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Bar"))).isNull();
  }

  @Test
  public void matchExactLabel() {
    var scrubber =
        new Scrubber(
            Config.newBuilder()
                .addRules(
                    Config.Rule.newBuilder()
                        .setMatcher(Config.Matcher.newBuilder().setLabel("//foo:bar")))
                .build());

    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Foo"))).isNotNull();
    assertThat(scrubber.forSpawn(createSpawn("//foo:barbaz", "Foo"))).isNull();
  }

  @Test
  public void matchUnionLabel() {
    var scrubber =
        new Scrubber(
            Config.newBuilder()
                .addRules(
                    Config.Rule.newBuilder()
                        .setMatcher(Config.Matcher.newBuilder().setLabel("//foo:bar|//spam:eggs")))
                .build());

    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Foo"))).isNotNull();
    assertThat(scrubber.forSpawn(createSpawn("//spam:eggs", "Foo"))).isNotNull();
    assertThat(scrubber.forSpawn(createSpawn("//quux:xyzzy", "Foo"))).isNull();
  }

  @Test
  public void matchWildcardLabel() {
    var scrubber =
        new Scrubber(
            Config.newBuilder()
                .addRules(
                    Config.Rule.newBuilder()
                        .setMatcher(Config.Matcher.newBuilder().setLabel("//foo:.*")))
                .build());

    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Foo"))).isNotNull();
    assertThat(scrubber.forSpawn(createSpawn("//foo:baz", "Foo"))).isNotNull();
    assertThat(scrubber.forSpawn(createSpawn("//spam:eggs", "Foo"))).isNull();
  }

  @Test
  public void rejectToolAction() {
    var scrubber =
        new Scrubber(
            Config.newBuilder()
                .addRules(
                    Config.Rule.newBuilder()
                        .setMatcher(
                            Config.Matcher.newBuilder().setLabel("//foo:bar").setMnemonic("Foo")))
                .build());

    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Foo"))).isNotNull();
    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Foo", /* forTool= */ true))).isNull();
  }

  @Test
  public void acceptToolAction() {
    var scrubber =
        new Scrubber(
            Config.newBuilder()
                .addRules(
                    Config.Rule.newBuilder()
                        .setMatcher(
                            Config.Matcher.newBuilder()
                                .setLabel("//foo:bar")
                                .setMnemonic("Foo")
                                .setMatchTools(true)))
                .build());

    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Foo"))).isNotNull();
    assertThat(scrubber.forSpawn(createSpawn("//foo:bar", "Foo", /* forTool= */ true))).isNotNull();
  }

  @Test
  public void noOmittedInputs() {
    var spawnScrubber =
        new Scrubber(Config.newBuilder().addRules(Config.Rule.getDefaultInstance()).build())
            .forSpawn(createSpawn());

    assertThat(spawnScrubber.shouldOmitInput(ActionInputHelper.fromPath("foo/bar"))).isFalse();
  }

  @Test
  public void exactOmittedInput() {
    var spawnScrubber =
        new Scrubber(
                Config.newBuilder()
                    .addRules(
                        Config.Rule.newBuilder()
                            .setTransform(
                                Config.Transform.newBuilder().addOmittedInputs("foo/bar")))
                    .build())
            .forSpawn(createSpawn());

    assertThat(spawnScrubber.shouldOmitInput(ActionInputHelper.fromPath("foo/bar"))).isTrue();
    assertThat(spawnScrubber.shouldOmitInput(ActionInputHelper.fromPath("foo/bar/baz"))).isFalse();
    assertThat(spawnScrubber.shouldOmitInput(ActionInputHelper.fromPath("bazel-out/foo/bar")))
        .isFalse();
  }

  @Test
  public void wildcardOmittedInput() {
    var spawnScrubber =
        new Scrubber(
                Config.newBuilder()
                    .addRules(
                        Config.Rule.newBuilder()
                            .setTransform(
                                Config.Transform.newBuilder().addOmittedInputs("foo/bar.*")))
                    .build())
            .forSpawn(createSpawn());

    assertThat(spawnScrubber.shouldOmitInput(ActionInputHelper.fromPath("foo/bar"))).isTrue();
    assertThat(spawnScrubber.shouldOmitInput(ActionInputHelper.fromPath("foo/bar/baz"))).isTrue();
    assertThat(spawnScrubber.shouldOmitInput(ActionInputHelper.fromPath("bazel-out/foo/bar")))
        .isFalse();
  }

  @Test
  public void multipleOmittedInputs() {
    var spawnScrubber =
        new Scrubber(
                Config.newBuilder()
                    .addRules(
                        Config.Rule.newBuilder()
                            .setTransform(
                                Config.Transform.newBuilder()
                                    .addOmittedInputs("foo/bar")
                                    .addOmittedInputs("spam/eggs")))
                    .build())
            .forSpawn(createSpawn());

    assertThat(spawnScrubber.shouldOmitInput(ActionInputHelper.fromPath("foo/bar"))).isTrue();
    assertThat(spawnScrubber.shouldOmitInput(ActionInputHelper.fromPath("spam/eggs"))).isTrue();
    assertThat(spawnScrubber.shouldOmitInput(ActionInputHelper.fromPath("foo/bar/baz"))).isFalse();
    assertThat(spawnScrubber.shouldOmitInput(ActionInputHelper.fromPath("bazel-out/foo/bar")))
        .isFalse();
    assertThat(spawnScrubber.shouldOmitInput(ActionInputHelper.fromPath("spam/eggs/bacon")))
        .isFalse();
    assertThat(spawnScrubber.shouldOmitInput(ActionInputHelper.fromPath("bazel-out/spam/eggs")))
        .isFalse();
  }

  @Test
  public void doNotScrubEmptyMarker() {
    var spawnScrubber =
        new Scrubber(
                Config.newBuilder()
                    .addRules(
                        Config.Rule.newBuilder()
                            .setTransform(Config.Transform.newBuilder().addOmittedInputs(".*")))
                    .build())
            .forSpawn(createSpawn());

    assertThat(spawnScrubber.shouldOmitInput(VirtualActionInput.EMPTY_MARKER)).isFalse();
  }

  @Test
  public void simpleArgReplacement() {
    var spawnScrubber =
        new Scrubber(
                Config.newBuilder()
                    .addRules(
                        Config.Rule.newBuilder()
                            .setTransform(
                                Config.Transform.newBuilder()
                                    .addArgReplacements(
                                        Config.Replacement.newBuilder()
                                            .setSource("foo")
                                            .setTarget("bar"))))
                    .build())
            .forSpawn(createSpawn());

    assertThat(spawnScrubber.transformArgument("foo")).isEqualTo("bar");
    assertThat(spawnScrubber.transformArgument("abcfooxyz")).isEqualTo("abcbarxyz");
    assertThat(spawnScrubber.transformArgument("bar")).isEqualTo("bar");
    assertThat(spawnScrubber.transformArgument("foofoo")).isEqualTo("barfoo");
  }

  @Test
  public void anchoredArgReplacement() {
    var spawnScrubber =
        new Scrubber(
                Config.newBuilder()
                    .addRules(
                        Config.Rule.newBuilder()
                            .setTransform(
                                Config.Transform.newBuilder()
                                    .addArgReplacements(
                                        Config.Replacement.newBuilder()
                                            .setSource("^foo$")
                                            .setTarget("bar"))))
                    .build())
            .forSpawn(createSpawn());

    assertThat(spawnScrubber.transformArgument("foo")).isEqualTo("bar");
    assertThat(spawnScrubber.transformArgument("abcfooxyz")).isEqualTo("abcfooxyz");
  }

  @Test
  public void wildcardArgReplacement() {
    var spawnScrubber =
        new Scrubber(
                Config.newBuilder()
                    .addRules(
                        Config.Rule.newBuilder()
                            .setTransform(
                                Config.Transform.newBuilder()
                                    .addArgReplacements(
                                        Config.Replacement.newBuilder()
                                            .setSource("foo[12]")
                                            .setTarget("bar"))))
                    .build())
            .forSpawn(createSpawn());

    assertThat(spawnScrubber.transformArgument("foo1")).isEqualTo("bar");
    assertThat(spawnScrubber.transformArgument("foo2")).isEqualTo("bar");
    assertThat(spawnScrubber.transformArgument("foo3")).isEqualTo("foo3");
  }

  @Test
  public void multipleArgReplacements() {
    var spawnScrubber =
        new Scrubber(
                Config.newBuilder()
                    .addRules(
                        Config.Rule.newBuilder()
                            .setTransform(
                                Config.Transform.newBuilder()
                                    .addArgReplacements(
                                        Config.Replacement.newBuilder()
                                            .setSource("foo")
                                            .setTarget("bar"))
                                    .addArgReplacements(
                                        Config.Replacement.newBuilder()
                                            .setSource("spam")
                                            .setTarget("eggs"))))
                    .build())
            .forSpawn(createSpawn());

    assertThat(spawnScrubber.transformArgument("abcfoo123spamxyz")).isEqualTo("abcbar123eggsxyz");
    assertThat(spawnScrubber.transformArgument("abcfoo")).isEqualTo("abcbar");
    assertThat(spawnScrubber.transformArgument("abcspam")).isEqualTo("abceggs");
    assertThat(spawnScrubber.transformArgument("bareggs")).isEqualTo("bareggs");
  }

  @Test
  public void withoutSalt() {
    var spawnScrubber =
        new Scrubber(Config.newBuilder().addRules(Config.Rule.getDefaultInstance()).build())
            .forSpawn(createSpawn());

    assertThat(spawnScrubber.getSalt()).isEmpty();
  }

  @Test
  public void withSalt() {
    var spawnScrubber =
        new Scrubber(
                Config.newBuilder()
                    .addRules(
                        Config.Rule.newBuilder()
                            .setTransform(Config.Transform.newBuilder().setSalt("NaCl")))
                    .build())
            .forSpawn(createSpawn());

    assertThat(spawnScrubber.getSalt()).isEqualTo("NaCl");
  }

  @Test
  public void orthogonalRules() {
    var scrubber =
        new Scrubber(
            Config.newBuilder()
                .addRules(
                    Config.Rule.newBuilder()
                        .setMatcher(Config.Matcher.newBuilder().setLabel("//foo:bar"))
                        .setTransform(
                            Config.Transform.newBuilder()
                                .addArgReplacements(
                                    Config.Replacement.newBuilder()
                                        .setSource("foo")
                                        .setTarget("bar"))))
                .addRules(
                    Config.Rule.newBuilder()
                        .setMatcher(Config.Matcher.newBuilder().setLabel("//spam:eggs"))
                        .setTransform(
                            Config.Transform.newBuilder()
                                .addArgReplacements(
                                    Config.Replacement.newBuilder()
                                        .setSource("spam")
                                        .setTarget("eggs"))))
                .build());

    SpawnScrubber spawnScrubberForFooBar = scrubber.forSpawn(createSpawn("//foo:bar", "Foo"));
    assertThat(spawnScrubberForFooBar).isNotNull();
    assertThat(spawnScrubberForFooBar.transformArgument("foospam")).isEqualTo("barspam");

    SpawnScrubber spawnScrubberForSpamEggs = scrubber.forSpawn(createSpawn("//spam:eggs", "Spam"));
    assertThat(spawnScrubberForSpamEggs).isNotNull();
    assertThat(spawnScrubberForSpamEggs.transformArgument("foospam")).isEqualTo("fooeggs");
  }

  @Test
  public void lastRuleWins() {
    var spawnScrubber =
        new Scrubber(
                Config.newBuilder()
                    .addRules(
                        Config.Rule.newBuilder()
                            .setTransform(
                                Config.Transform.newBuilder()
                                    .addArgReplacements(
                                        Config.Replacement.newBuilder()
                                            .setSource("foo")
                                            .setTarget("bar"))))
                    .addRules(
                        Config.Rule.newBuilder()
                            .setTransform(
                                Config.Transform.newBuilder()
                                    .addArgReplacements(
                                        Config.Replacement.newBuilder()
                                            .setSource("spam")
                                            .setTarget("eggs"))))
                    .build())
            .forSpawn(createSpawn());

    assertThat(spawnScrubber.transformArgument("foospam")).isEqualTo("fooeggs");
  }

  private static Spawn createSpawn() {
    return createSpawn("//foo:bar", "Foo");
  }

  private static Spawn createSpawn(String label, String mnemonic) {
    return createSpawn(label, mnemonic, /* forTool= */ false);
  }

  private static Spawn createSpawn(String label, String mnemonic, boolean forTool) {
    return new SpawnBuilder("cmd")
        .withOwnerLabel(label)
        .withMnemonic(mnemonic)
        .setBuiltForToolConfiguration(forTool)
        .build();
  }
}
