// 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.assertThrows;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.testing.EqualsTester;
import com.google.devtools.build.lib.analysis.AspectCollection.AspectDeps;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
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 final class DependencyTest extends AnalysisTestCase {

  @Test
  public void withNullConfiguration_BasicAccessors() throws Exception {
    Dependency nullDep =
        Dependency.builder().withNullConfiguration().setLabel(Label.parseCanonical("//a")).build();

    assertThat(nullDep.getLabel()).isEqualTo(Label.parseCanonical("//a"));
    assertThat(nullDep.getConfiguration()).isNull();
    assertThat(nullDep.getAspects().getUsedAspects()).isEmpty();
  }

  @Test
  public void withConfiguration_BasicAccessors() throws Exception {
    update();
    Dependency targetDep =
        Dependency.builder()
            .setLabel(Label.parseCanonical("//a"))
            .setConfiguration(getTargetConfiguration())
            .build();

    assertThat(targetDep.getLabel()).isEqualTo(Label.parseCanonical("//a"));
    assertThat(targetDep.getConfiguration()).isEqualTo(getTargetConfiguration());
    assertThat(targetDep.getAspects().getUsedAspects()).isEmpty();
  }

  @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.builder()
            .setLabel(Label.parseCanonical("//a"))
            .setConfiguration(getTargetConfiguration())
            .setAspects(twoAspects)
            .build();

    assertThat(targetDep.getLabel()).isEqualTo(Label.parseCanonical("//a"));
    assertThat(targetDep.getConfiguration()).isEqualTo(getTargetConfiguration());
    assertThat(targetDep.getAspects()).isEqualTo(twoAspects);
  }

  @Test
  public void withConfigurationAndAspects_rejectsNullConfig() {
    AspectDescriptor simpleAspect = new AspectDescriptor(TestAspects.SIMPLE_ASPECT);
    AspectDescriptor attributeAspect = new AspectDescriptor(TestAspects.ATTRIBUTE_ASPECT);
    AspectCollection twoAspects = AspectCollection.createForTests(simpleAspect, attributeAspect);

    assertThrows(
        IllegalStateException.class,
        () ->
            Dependency.builder()
                .setLabel(Label.parseCanonical("//a"))
                .setConfiguration(null)
                .setAspects(twoAspects)
                .build());
  }

  @Test
  public void withConfigurationAndAspects_AllowsEmptyAspectSet() throws Exception {
    update();
    Dependency dep =
        Dependency.builder()
            .setLabel(Label.parseCanonical("//a"))
            .setConfiguration(getTargetConfiguration())
            .build();
    // Here we're also checking that this doesn't throw an exception. No boom? OK. Good.
    assertThat(dep.getAspects().getUsedAspects()).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));
    Dependency targetDep =
        Dependency.builder()
            .setLabel(Label.parseCanonical("//a"))
            .setConfiguration(getTargetConfiguration())
            .setAspects(aspects)
            .build();

    assertThat(targetDep.getLabel()).isEqualTo(Label.parseCanonical("//a"));
    assertThat(targetDep.getConfiguration()).isEqualTo(getTargetConfiguration());
    assertThat(Iterables.transform(targetDep.getAspects().getUsedAspects(), AspectDeps::getAspect))
        .containsExactly(simpleAspect, attributeAspect);
  }

  @Test
  public void withConfiguredAspects_AllowsEmptyAspectMap() throws Exception {
    update();
    Dependency dep =
        Dependency.builder()
            .setLabel(Label.parseCanonical("//a"))
            .setConfiguration(getTargetConfiguration())
            .setAspects(AspectCollection.EMPTY)
            .build();
    // Here we're also checking that this doesn't throw an exception. No boom? OK. Good.
    assertThat(dep.getAspects().getUsedAspects()).isEmpty();
  }

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

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

    BuildConfigurationValue host = getHostConfiguration();
    BuildConfigurationValue 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;

    new EqualsTester()
        .addEqualityGroup(
            // base set: //a, host configuration, normal aspect set
            Dependency.builder().setLabel(a).setConfiguration(host).setAspects(twoAspects).build(),
            Dependency.builder()
                .setLabel(aExplicit)
                .setConfiguration(host)
                .setAspects(twoAspects)
                .build(),
            Dependency.builder()
                .setLabel(a)
                .setConfiguration(host)
                .setAspects(inverseAspects)
                .build(),
            Dependency.builder()
                .setLabel(aExplicit)
                .setConfiguration(host)
                .setAspects(inverseAspects)
                .build(),
            Dependency.builder().setLabel(a).setConfiguration(host).setAspects(twoAspects).build(),
            Dependency.builder()
                .setLabel(aExplicit)
                .setConfiguration(host)
                .setAspects(twoAspects)
                .build())
        .addEqualityGroup(
            // base set but with label //b
            Dependency.builder().setLabel(b).setConfiguration(host).setAspects(twoAspects).build(),
            Dependency.builder()
                .setLabel(b)
                .setConfiguration(host)
                .setAspects(inverseAspects)
                .build(),
            Dependency.builder().setLabel(b).setConfiguration(host).setAspects(twoAspects).build())
        .addEqualityGroup(
            // base set but with target configuration
            Dependency.builder()
                .setLabel(a)
                .setConfiguration(target)
                .setAspects(twoAspects)
                .build(),
            Dependency.builder()
                .setLabel(aExplicit)
                .setConfiguration(target)
                .setAspects(twoAspects)
                .build(),
            Dependency.builder()
                .setLabel(a)
                .setConfiguration(target)
                .setAspects(inverseAspects)
                .build(),
            Dependency.builder()
                .setLabel(aExplicit)
                .setConfiguration(target)
                .setAspects(inverseAspects)
                .build(),
            Dependency.builder()
                .setLabel(a)
                .setConfiguration(target)
                .setAspects(twoAspects)
                .build(),
            Dependency.builder()
                .setLabel(aExplicit)
                .setConfiguration(target)
                .setAspects(twoAspects)
                .build())
        .addEqualityGroup(
            // base set but with null configuration
            Dependency.builder().withNullConfiguration().setLabel(a).build(),
            Dependency.builder().withNullConfiguration().setLabel(aExplicit).build())
        .addEqualityGroup(
            // base set but with different aspects
            Dependency.builder()
                .setLabel(a)
                .setConfiguration(host)
                .setAspects(differentAspects)
                .build(),
            Dependency.builder()
                .setLabel(aExplicit)
                .setConfiguration(host)
                .setAspects(differentAspects)
                .build(),
            Dependency.builder()
                .setLabel(a)
                .setConfiguration(host)
                .setAspects(differentAspects)
                .build(),
            Dependency.builder()
                .setLabel(aExplicit)
                .setConfiguration(host)
                .setAspects(differentAspects)
                .build())
        .addEqualityGroup(
            // base set but with label //b and target configuration
            Dependency.builder()
                .setLabel(b)
                .setConfiguration(target)
                .setAspects(twoAspects)
                .build(),
            Dependency.builder()
                .setLabel(b)
                .setConfiguration(target)
                .setAspects(inverseAspects)
                .build(),
            Dependency.builder()
                .setLabel(b)
                .setConfiguration(target)
                .setAspects(twoAspects)
                .build())
        .addEqualityGroup(
            // base set but with label //b and null configuration
            Dependency.builder().withNullConfiguration().setLabel(b).build())
        .addEqualityGroup(
            // base set but with label //b and different aspects
            Dependency.builder()
                .setLabel(b)
                .setConfiguration(host)
                .setAspects(differentAspects)
                .build(),
            Dependency.builder()
                .setLabel(b)
                .setConfiguration(host)
                .setAspects(differentAspects)
                .build())
        .addEqualityGroup(
            // base set but with target configuration and different aspects
            Dependency.builder()
                .setLabel(a)
                .setConfiguration(target)
                .setAspects(differentAspects)
                .build(),
            Dependency.builder()
                .setLabel(aExplicit)
                .setConfiguration(target)
                .setAspects(differentAspects)
                .build(),
            Dependency.builder()
                .setLabel(a)
                .setConfiguration(target)
                .setAspects(differentAspects)
                .build(),
            Dependency.builder()
                .setLabel(aExplicit)
                .setConfiguration(target)
                .setAspects(differentAspects)
                .build())
        .addEqualityGroup(
            // inverse of base set: //b, target configuration, different aspects
            Dependency.builder()
                .setLabel(b)
                .setConfiguration(target)
                .setAspects(differentAspects)
                .build(),
            Dependency.builder()
                .setLabel(b)
                .setConfiguration(target)
                .setAspects(differentAspects)
                .build())
        .addEqualityGroup(
            // base set but with no aspects
            Dependency.builder().setLabel(a).setConfiguration(host).build(),
            Dependency.builder().setLabel(aExplicit).setConfiguration(host).build(),
            Dependency.builder().setLabel(a).setConfiguration(host).setAspects(noAspects).build(),
            Dependency.builder()
                .setLabel(aExplicit)
                .setConfiguration(host)
                .setAspects(noAspects)
                .build(),
            Dependency.builder().setLabel(a).setConfiguration(host).setAspects(noAspects).build(),
            Dependency.builder()
                .setLabel(aExplicit)
                .setConfiguration(host)
                .setAspects(noAspects)
                .build())
        .addEqualityGroup(
            // base set but with label //b and no aspects
            Dependency.builder().setLabel(b).setConfiguration(host).build(),
            Dependency.builder().setLabel(b).setConfiguration(host).setAspects(noAspects).build(),
            Dependency.builder().setLabel(b).setConfiguration(host).setAspects(noAspects).build())
        .addEqualityGroup(
            // base set but with target configuration and no aspects
            Dependency.builder().setLabel(a).setConfiguration(target).build(),
            Dependency.builder().setLabel(aExplicit).setConfiguration(target).build(),
            Dependency.builder().setLabel(a).setConfiguration(target).setAspects(noAspects).build(),
            Dependency.builder()
                .setLabel(aExplicit)
                .setConfiguration(target)
                .setAspects(noAspects)
                .build(),
            Dependency.builder().setLabel(a).setConfiguration(target).setAspects(noAspects).build(),
            Dependency.builder()
                .setLabel(aExplicit)
                .setConfiguration(target)
                .setAspects(noAspects)
                .build())
        .addEqualityGroup(
            // inverse of base set: //b, target configuration, no aspects
            Dependency.builder().setLabel(b).setConfiguration(target).build(),
            Dependency.builder().setLabel(b).setConfiguration(target).setAspects(noAspects).build(),
            Dependency.builder().setLabel(b).setConfiguration(target).setAspects(noAspects).build())
        .testEquals();
  }
}
