// Copyright 2015 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.analysis;

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

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.HostTransition;
import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
import com.google.devtools.build.lib.analysis.util.AnalysisTestCase;
import com.google.devtools.build.lib.analysis.util.TestAspects;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.AspectDescriptor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for {@link Dependency}.
 *
 * <p>Although this is just a data class, we need a way to create a configuration.
 */
@RunWith(JUnit4.class)
public class DependencyTest extends AnalysisTestCase {
  @Test
  public void withNullConfiguration_BasicAccessors() throws Exception {
    Dependency nullDep = Dependency.withNullConfiguration(Label.parseAbsolute("//a"));

    assertThat(nullDep.getLabel()).isEqualTo(Label.parseAbsolute("//a"));
    assertThat(nullDep.hasExplicitConfiguration()).isTrue();
    assertThat(nullDep.getConfiguration()).isNull();
    assertThat(nullDep.getAspects().getAllAspects()).isEmpty();

    try {
      nullDep.getTransition();
      fail("withNullConfiguration-created Dependencies should throw ISE on getTransition()");
    } catch (IllegalStateException ex) {
      // good. expected.
    }
  }

  @Test
  public void withConfiguration_BasicAccessors() throws Exception {
    update();
    Dependency targetDep =
        Dependency.withConfiguration(Label.parseAbsolute("//a"), getTargetConfiguration());

    assertThat(targetDep.getLabel()).isEqualTo(Label.parseAbsolute("//a"));
    assertThat(targetDep.hasExplicitConfiguration()).isTrue();
    assertThat(targetDep.getConfiguration()).isEqualTo(getTargetConfiguration());
    assertThat(targetDep.getAspects().getAllAspects()).isEmpty();

    try {
      targetDep.getTransition();
      fail("withConfiguration-created Dependencies should throw ISE on getTransition()");
    } catch (IllegalStateException ex) {
      // good. expected.
    }
  }

  @Test
  public void withConfigurationAndAspects_BasicAccessors() throws Exception {
    update();
    AspectDescriptor simpleAspect = new AspectDescriptor(TestAspects.SIMPLE_ASPECT);
    AspectDescriptor attributeAspect = new AspectDescriptor(TestAspects.ATTRIBUTE_ASPECT);
    AspectCollection twoAspects = AspectCollection.createForTests(
        ImmutableSet.of(simpleAspect, attributeAspect));
    Dependency targetDep =
        Dependency.withConfigurationAndAspects(
            Label.parseAbsolute("//a"), getTargetConfiguration(), twoAspects);

    assertThat(targetDep.getLabel()).isEqualTo(Label.parseAbsolute("//a"));
    assertThat(targetDep.hasExplicitConfiguration()).isTrue();
    assertThat(targetDep.getConfiguration()).isEqualTo(getTargetConfiguration());
    assertThat(targetDep.getAspects()).isEqualTo(twoAspects);
    assertThat(targetDep.getAspectConfiguration(simpleAspect)).isEqualTo(getTargetConfiguration());
    assertThat(targetDep.getAspectConfiguration(attributeAspect))
        .isEqualTo(getTargetConfiguration());

    try {
      targetDep.getTransition();
      fail("withConfigurationAndAspects-created Dependencies should throw ISE on getTransition()");
    } catch (IllegalStateException ex) {
      // good. that's what I WANTED to happen.
    }
  }

  @Test
  public void withConfigurationAndAspects_RejectsNullConfigWithNPE() throws Exception {
    // Although the NullPointerTester should check this, this test invokes a different code path,
    // because it includes aspects (which the NPT test will not).
    AspectDescriptor simpleAspect = new AspectDescriptor(TestAspects.SIMPLE_ASPECT);
    AspectDescriptor attributeAspect = new AspectDescriptor(TestAspects.ATTRIBUTE_ASPECT);
    AspectCollection twoAspects = AspectCollection.createForTests(simpleAspect, attributeAspect);

    try {
      Dependency.withConfigurationAndAspects(Label.parseAbsolute("//a"), null, twoAspects);
      fail("should not be allowed to create a dependency with a null configuration");
    } catch (NullPointerException expected) {
      // good. you fell rrrrright into my trap.
    }
  }

  @Test
  public void withConfigurationAndAspects_AllowsEmptyAspectSet() throws Exception {
    update();
    Dependency dep =
        Dependency.withConfigurationAndAspects(
            Label.parseAbsolute("//a"),
            getTargetConfiguration(),
            AspectCollection.EMPTY);
    // Here we're also checking that this doesn't throw an exception. No boom? OK. Good.
    assertThat(dep.getAspects().getAllAspects()).isEmpty();
  }

  @Test
  public void withConfiguredAspects_BasicAccessors() throws Exception {
    update();
    AspectDescriptor simpleAspect = new AspectDescriptor(TestAspects.SIMPLE_ASPECT);
    AspectDescriptor attributeAspect = new AspectDescriptor(TestAspects.ATTRIBUTE_ASPECT);
    AspectCollection aspects =
        AspectCollection.createForTests(ImmutableSet.of(simpleAspect, attributeAspect));
    ImmutableMap<AspectDescriptor, BuildConfiguration> twoAspectMap = ImmutableMap.of(
        simpleAspect, getTargetConfiguration(), attributeAspect, getHostConfiguration());
    Dependency targetDep =
        Dependency.withConfiguredAspects(
            Label.parseAbsolute("//a"), getTargetConfiguration(), aspects, twoAspectMap);

    assertThat(targetDep.getLabel()).isEqualTo(Label.parseAbsolute("//a"));
    assertThat(targetDep.hasExplicitConfiguration()).isTrue();
    assertThat(targetDep.getConfiguration()).isEqualTo(getTargetConfiguration());
    assertThat(targetDep.getAspects().getAllAspects())
        .containsExactly(simpleAspect, attributeAspect);
    assertThat(targetDep.getAspectConfiguration(simpleAspect)).isEqualTo(getTargetConfiguration());
    assertThat(targetDep.getAspectConfiguration(attributeAspect))
        .isEqualTo(getHostConfiguration());

    try {
      targetDep.getTransition();
      fail("withConfiguredAspects-created Dependencies should throw ISE on getTransition()");
    } catch (IllegalStateException ex) {
      // good. all according to keikaku. (TL note: keikaku means plan)
    }
  }


  @Test
  public void withConfiguredAspects_AllowsEmptyAspectMap() throws Exception {
    update();
    Dependency dep =
        Dependency.withConfiguredAspects(
            Label.parseAbsolute("//a"), getTargetConfiguration(),
            AspectCollection.EMPTY,
            ImmutableMap.<AspectDescriptor, BuildConfiguration>of());
    // Here we're also checking that this doesn't throw an exception. No boom? OK. Good.
    assertThat(dep.getAspects().getAllAspects()).isEmpty();
  }

  @Test
  public void withTransitionAndAspects_BasicAccessors() throws Exception {
    AspectDescriptor simpleAspect = new AspectDescriptor(TestAspects.SIMPLE_ASPECT);
    AspectDescriptor attributeAspect = new AspectDescriptor(TestAspects.ATTRIBUTE_ASPECT);
    AspectCollection twoAspects = AspectCollection.createForTests(
        ImmutableSet.of(simpleAspect, attributeAspect));
    Dependency hostDep =
        Dependency.withTransitionAndAspects(
            Label.parseAbsolute("//a"), HostTransition.INSTANCE, twoAspects);

    assertThat(hostDep.getLabel()).isEqualTo(Label.parseAbsolute("//a"));
    assertThat(hostDep.hasExplicitConfiguration()).isFalse();
    assertThat(hostDep.getAspects().getAllAspects())
        .containsExactlyElementsIn(twoAspects.getAllAspects());
    assertThat(hostDep.getTransition().isHostTransition()).isTrue();

    try {
      hostDep.getConfiguration();
      fail("withTransitionAndAspects-created Dependencies should throw ISE on getConfiguration()");
    } catch (IllegalStateException ex) {
      // good. I knew you would do that.
    }

    try {
      hostDep.getAspectConfiguration(simpleAspect);
      fail("withTransitionAndAspects-created Dependencies should throw ISE on "
          + "getAspectConfiguration()");
    } catch (IllegalStateException ex) {
      // good. you're so predictable.
    }

    try {
      hostDep.getAspectConfiguration(attributeAspect);
      fail("withTransitionAndAspects-created Dependencies should throw ISE on "
          + "getAspectConfiguration()");
    } catch (IllegalStateException ex) {
      // good. you're so predictable.
    }
  }

  @Test
  public void withTransitionAndAspects_AllowsEmptyAspectSet() throws Exception {
    update();
    Dependency dep =
        Dependency.withTransitionAndAspects(
            Label.parseAbsolute("//a"), HostTransition.INSTANCE,
            AspectCollection.EMPTY);
    // Here we're also checking that this doesn't throw an exception. No boom? OK. Good.
    assertThat(dep.getAspects().getAllAspects()).isEmpty();
  }

  @Test
  public void factoriesPassNullableTester() throws Exception {
    update();

    new NullPointerTester()
        .setDefault(Label.class, Label.parseAbsolute("//a"))
        .setDefault(BuildConfiguration.class, getTargetConfiguration())
        .testAllPublicStaticMethods(Dependency.class);
  }

  @Test
  public void equalsPassesEqualsTester() throws Exception {
    update();

    Label a = Label.parseAbsolute("//a");
    Label aExplicit = Label.parseAbsolute("//a:a");
    Label b = Label.parseAbsolute("//b");

    BuildConfiguration host = getHostConfiguration();
    BuildConfiguration target = getTargetConfiguration();

    AspectDescriptor simpleAspect = new AspectDescriptor(TestAspects.SIMPLE_ASPECT);
    AspectDescriptor attributeAspect = new AspectDescriptor(TestAspects.ATTRIBUTE_ASPECT);
    AspectDescriptor errorAspect = new AspectDescriptor(TestAspects.ERROR_ASPECT);

    AspectCollection twoAspects =
        AspectCollection.createForTests(simpleAspect, attributeAspect);
    AspectCollection inverseAspects =
        AspectCollection.createForTests(attributeAspect, simpleAspect);
    AspectCollection differentAspects =
        AspectCollection.createForTests(attributeAspect, errorAspect);
    AspectCollection noAspects = AspectCollection.EMPTY;

    ImmutableMap<AspectDescriptor, BuildConfiguration> twoAspectsHostMap =
        ImmutableMap.of(simpleAspect, host, attributeAspect, host);
    ImmutableMap<AspectDescriptor, BuildConfiguration> twoAspectsTargetMap =
        ImmutableMap.of(simpleAspect, target, attributeAspect, target);
    ImmutableMap<AspectDescriptor, BuildConfiguration> differentAspectsHostMap =
        ImmutableMap.of(attributeAspect, host, errorAspect, host);
    ImmutableMap<AspectDescriptor, BuildConfiguration> differentAspectsTargetMap =
        ImmutableMap.of(attributeAspect, target, errorAspect, target);
    ImmutableMap<AspectDescriptor, BuildConfiguration> noAspectsMap =
        ImmutableMap.<AspectDescriptor, BuildConfiguration>of();

    new EqualsTester()
        .addEqualityGroup(
            // base set: //a, host configuration, normal aspect set
            Dependency.withConfigurationAndAspects(a, host, twoAspects),
            Dependency.withConfigurationAndAspects(aExplicit, host, twoAspects),
            Dependency.withConfigurationAndAspects(a, host, inverseAspects),
            Dependency.withConfigurationAndAspects(aExplicit, host, inverseAspects),
            Dependency.withConfiguredAspects(a, host, twoAspects, twoAspectsHostMap),
            Dependency.withConfiguredAspects(aExplicit, host, twoAspects, twoAspectsHostMap))
        .addEqualityGroup(
            // base set but with label //b
            Dependency.withConfigurationAndAspects(b, host, twoAspects),
            Dependency.withConfigurationAndAspects(b, host, inverseAspects),
            Dependency.withConfiguredAspects(b, host, twoAspects, twoAspectsHostMap))
        .addEqualityGroup(
            // base set but with target configuration
            Dependency.withConfigurationAndAspects(a, target, twoAspects),
            Dependency.withConfigurationAndAspects(aExplicit, target, twoAspects),
            Dependency.withConfigurationAndAspects(a, target, inverseAspects),
            Dependency.withConfigurationAndAspects(aExplicit, target, inverseAspects),
            Dependency.withConfiguredAspects(a, target, twoAspects, twoAspectsTargetMap),
            Dependency.withConfiguredAspects(aExplicit, target, twoAspects, twoAspectsTargetMap))
        .addEqualityGroup(
            // base set but with null configuration
            Dependency.withNullConfiguration(a),
            Dependency.withNullConfiguration(aExplicit))
        .addEqualityGroup(
            // base set but with different aspects
            Dependency.withConfigurationAndAspects(a, host, differentAspects),
            Dependency.withConfigurationAndAspects(aExplicit, host, differentAspects),
            Dependency.withConfiguredAspects(
                a, host, differentAspects, differentAspectsHostMap),
            Dependency.withConfiguredAspects(
                aExplicit, host, differentAspects, differentAspectsHostMap))
        .addEqualityGroup(
            // base set but with label //b and target configuration
            Dependency.withConfigurationAndAspects(b, target, twoAspects),
            Dependency.withConfigurationAndAspects(b, target, inverseAspects),
            Dependency.withConfiguredAspects(b, target,
                twoAspects, twoAspectsTargetMap))
        .addEqualityGroup(
            // base set but with label //b and null configuration
            Dependency.withNullConfiguration(b))
        .addEqualityGroup(
            // base set but with label //b and different aspects
            Dependency.withConfigurationAndAspects(b, host, differentAspects),
            Dependency.withConfiguredAspects(
                b, host, differentAspects, differentAspectsHostMap))
        .addEqualityGroup(
            // base set but with target configuration and different aspects
            Dependency.withConfigurationAndAspects(a, target, differentAspects),
            Dependency.withConfigurationAndAspects(aExplicit, target, differentAspects),
            Dependency.withConfiguredAspects(
                a, target, differentAspects, differentAspectsTargetMap),
            Dependency.withConfiguredAspects(
                aExplicit, target, differentAspects, differentAspectsTargetMap))
        .addEqualityGroup(
            // inverse of base set: //b, target configuration, different aspects
            Dependency.withConfigurationAndAspects(b, target, differentAspects),
            Dependency.withConfiguredAspects(
                b, target, differentAspects, differentAspectsTargetMap))
        .addEqualityGroup(
            // base set but with no aspects
            Dependency.withConfiguration(a, host),
            Dependency.withConfiguration(aExplicit, host),
            Dependency.withConfigurationAndAspects(a, host, noAspects),
            Dependency.withConfigurationAndAspects(aExplicit, host, noAspects),
            Dependency.withConfiguredAspects(a, host, noAspects, noAspectsMap),
            Dependency.withConfiguredAspects(aExplicit, host, noAspects, noAspectsMap))
        .addEqualityGroup(
            // base set but with label //b and no aspects
            Dependency.withConfiguration(b, host),
            Dependency.withConfigurationAndAspects(b, host, noAspects),
            Dependency.withConfiguredAspects(b, host, noAspects, noAspectsMap))
        .addEqualityGroup(
            // base set but with target configuration and no aspects
            Dependency.withConfiguration(a, target),
            Dependency.withConfiguration(aExplicit, target),
            Dependency.withConfigurationAndAspects(a, target, noAspects),
            Dependency.withConfigurationAndAspects(aExplicit, target, noAspects),
            Dependency.withConfiguredAspects(a, target, noAspects, noAspectsMap),
            Dependency.withConfiguredAspects(aExplicit, target, noAspects, noAspectsMap))
        .addEqualityGroup(
            // inverse of base set: //b, target configuration, no aspects
            Dependency.withConfiguration(b, target),
            Dependency.withConfigurationAndAspects(b, target, noAspects),
            Dependency.withConfiguredAspects(b, target, noAspects, noAspectsMap))
        .addEqualityGroup(
            // base set but with transition HOST
            Dependency.withTransitionAndAspects(a, HostTransition.INSTANCE, twoAspects),
            Dependency.withTransitionAndAspects(
                aExplicit, HostTransition.INSTANCE, twoAspects),
            Dependency.withTransitionAndAspects(a, HostTransition.INSTANCE, inverseAspects),
            Dependency.withTransitionAndAspects(
                aExplicit, HostTransition.INSTANCE, inverseAspects))
        .addEqualityGroup(
            // base set but with transition HOST and different aspects
            Dependency.withTransitionAndAspects(a, HostTransition.INSTANCE, differentAspects),
            Dependency.withTransitionAndAspects(
                aExplicit, HostTransition.INSTANCE, differentAspects))
        .addEqualityGroup(
            // base set but with transition HOST and label //b
            Dependency.withTransitionAndAspects(b, HostTransition.INSTANCE, twoAspects),
            Dependency.withTransitionAndAspects(b, HostTransition.INSTANCE, inverseAspects))
        .addEqualityGroup(
            // inverse of base set: transition HOST, label //b, different aspects
            Dependency.withTransitionAndAspects(b, HostTransition.INSTANCE, differentAspects),
            Dependency.withTransitionAndAspects(b, HostTransition.INSTANCE, differentAspects))
        .addEqualityGroup(
            // base set but with transition NONE
            Dependency.withTransitionAndAspects(a, NoTransition.INSTANCE, twoAspects),
            Dependency.withTransitionAndAspects(aExplicit, NoTransition.INSTANCE, twoAspects),
            Dependency.withTransitionAndAspects(a, NoTransition.INSTANCE, inverseAspects),
            Dependency.withTransitionAndAspects(aExplicit, NoTransition.INSTANCE, inverseAspects))
        .addEqualityGroup(
            // base set but with transition NONE and different aspects
            Dependency.withTransitionAndAspects(a, NoTransition.INSTANCE, differentAspects),
            Dependency.withTransitionAndAspects(aExplicit, NoTransition.INSTANCE, differentAspects))
        .addEqualityGroup(
            // base set but with transition NONE and label //b
            Dependency.withTransitionAndAspects(b, NoTransition.INSTANCE, twoAspects),
            Dependency.withTransitionAndAspects(b, NoTransition.INSTANCE, inverseAspects))
        .addEqualityGroup(
            // inverse of base set: transition NONE, label //b, different aspects
            Dependency.withTransitionAndAspects(b, NoTransition.INSTANCE, differentAspects),
            Dependency.withTransitionAndAspects(b, NoTransition.INSTANCE, differentAspects))
        .testEquals();
  }
}
