// Copyright 2017 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.util;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.Arrays;

/**
 * Provides a simple API for creating custom rule classes for tests.
 *
 * <p>Use this whenever you want to test language-agnostic Bazel functionality, i.e. behavior that
 * isn't specific to individual rule implementations. If you find yourself searching through rule
 * implementations trying to find one that matches whatever you're trying to test, you probably
 * want this instead.
 *
 * <p>This prevents the anti-pattern of tests with commingled dependencies. For example, when a test
 * uses <code>cc_library</code> to test generic logic that <code>cc_library</code> happens to
 * provide, the test can break if the <code>cc_library</code> implementation changes. This means C++
 * rule developers have to understand the test to change C++ logic: a dependency that helps no one.
 *
 * <p>Even if C++ logic doesn't change, <code>cc_library</code> may not make it clear what's being
 * tested (e.g. "why is the "malloc" attribute used here?"). Using a mock rule class offers the
 * ability to write a clearer, more focused, easier to understand test (e.g.
 * <code>mock_rule(name = "foo", attr_that_tests_this_specific_test_logic = ":bar")</code).
 *
 * <p>Usage for a custom rule type that just needs to exist (no special attributes or behavior
 * needed):
 *
 * <pre>
 *   MockRule fooRule = () -> MockRule.define("foo_rule");
 * </pre>
 *
 * <p>Usage for custom attributes:
 *
 * <pre>
 *   MockRule fooRule = () -> MockRule.define("foo_rule", attr("some_attr", Type.STRING));
 * </pre>
 *
 * <p>Usage for arbitrary customization:
 *
 * <pre>
 *   MockRule fooRule = () -> MockRule.define(
 *       "foo_rule",
 *       (builder, env) ->
 *           builder
 *               .removeAttribute("tags")
 *               .requiresConfigurationFragments(FooConfiguration.class);
 *       );
 * </pre>
 *
 * Custom {@link RuleDefinition} ancestors and {@link RuleConfiguredTargetFactory} implementations
 * can also be specified:
 *
 * <pre>
 *   MockRule customAncestor = () -> MockRule.ancestor(BaseRule.class).define(...);
 *   MockRule customImpl = () -> MockRule.factory(FooRuleFactory.class).define(...);
 *   MockRule customEverything = () ->
 *       MockRule.ancestor(BaseRule.class).factory(FooRuleFactory.class).define(...);
 * </pre>
 *
 * When unspecified, {@link State#DEFAULT_ANCESTOR} and {@link State#DEFAULT_FACTORY} apply.
 *
 * <p>We use lambdas for custom rule classes because {@link ConfiguredRuleClassProvider} indexes
 * rule class definitions by their Java class names. So each definition has to have its own
 * unique Java class.
 *
 * <p>Both of the following forms are valid:
 *
 * <pre>MockRule fooRule = () -> MockRule.define("foo_rule");</pre>
 * <pre>RuleDefinition fooRule = (MockRule) () -> MockRule.define("foo_rule");</pre>
 *
 * <p>Use discretion in choosing your preferred form. The first is more compact. The second makes
 * it clearer that <code>fooRule</code> is a proper rule class definition.
 */
public interface MockRule extends RuleDefinition {
  // MockRule is designed to be easy to use. That doesn't necessarily mean its implementation is
  // easy to undestand.
  //
  // If you just want to mock a rule, it's best to rely on the interface javadoc above, rather than
  // trying to parse what's going on below. You really only need to understand the below if you want
  // to customize MockRule itself.

  /**
   * Container for the desired name and custom settings for this rule class.
   */
  class State {
    private final String name;
    private final MockRuleCustomBehavior customBehavior;
    private final Class<? extends RuleConfiguredTargetFactory> factory;
    private final ImmutableList<Class<? extends RuleDefinition>> ancestors;
    private final RuleClassType type;

    /** The default {@link RuleConfiguredTargetFactory} for this rule class. */
    private static final Class<? extends RuleConfiguredTargetFactory> DEFAULT_FACTORY =
        MockRuleDefaults.DefaultConfiguredTargetFactory.class;
    /** The default {@link RuleDefinition} for this rule class. */
    private static final ImmutableList<Class<? extends RuleDefinition>> DEFAULT_ANCESTORS =
        ImmutableList.of();

    State(String ruleClassName, MockRuleCustomBehavior customBehavior,
        Class<? extends RuleConfiguredTargetFactory> factory,
        ImmutableList<Class<? extends RuleDefinition>> ancestors,
        RuleClassType type) {
      this.name = Preconditions.checkNotNull(ruleClassName);
      this.customBehavior = Preconditions.checkNotNull(customBehavior);
      this.factory = factory;
      this.ancestors = ancestors;
      this.type = type;
    }

    public static class Builder {
      private Class<? extends RuleConfiguredTargetFactory> factory = DEFAULT_FACTORY;
      private ImmutableList<Class<? extends RuleDefinition>> ancestors = DEFAULT_ANCESTORS;
      private RuleClassType type = RuleClassType.NORMAL;

      @CanIgnoreReturnValue
      public Builder factory(Class<? extends RuleConfiguredTargetFactory> factory) {
        this.factory = factory;
        return this;
      }

      @CanIgnoreReturnValue
      public Builder ancestor(Class<? extends RuleDefinition>... ancestor) {
        this.ancestors = ImmutableList.copyOf(ancestor);
        return this;
      }

      @CanIgnoreReturnValue
      public Builder type(RuleClassType type) {
        this.type = type;
        return this;
      }

      public State define(String ruleClassName, Attribute.Builder<?>... attributes) {
        return build(ruleClassName,
            new MockRuleCustomBehavior.CustomAttributes(Arrays.asList(attributes)));
      }

      public State define(String ruleClassName, MockRuleCustomBehavior customBehavior) {
        return build(ruleClassName, customBehavior);
      }

      private State build(String ruleClassName, MockRuleCustomBehavior customBehavior) {
        return new State(ruleClassName, customBehavior, factory, ancestors, type);
      }
    }
  }

  /**
   * Sets a custom {@link RuleConfiguredTargetFactory} for this mock rule.
   *
   * <p>If not set, {@link State#DEFAULT_FACTORY} is used.
   */
  static State.Builder factory(Class<? extends RuleConfiguredTargetFactory> factory) {
    return new State.Builder().factory(factory);
  }

  /**
   * Sets a custom ancestor {@link RuleDefinition} for this mock rule.
   *
   * <p>If not set, {@link State#DEFAULT_ANCESTORS} is used.
   */
  static State.Builder ancestor(Class<? extends RuleDefinition>... ancestor) {
    return new State.Builder().ancestor(ancestor);
  }

  /**
   * Sets a custom {@link RuleClassType} for this mock rule.
   *
   * <p>If not set, {@link RuleClassType#NORMAL} is used.
   */
  static State.Builder type(RuleClassType type) {
    return new State.Builder().type(type);
  }

  /**
   * Returns a new {@link State} for this rule class with custom attributes. This is a convenience
   * method for lambda definitions:
   *
   * <pre>
   *   MockRule myRule = () -> MockRule.define("my_rule", attr("myattr", Type.STRING));
   * </pre>
   */
  static State define(String ruleClassName, Attribute.Builder<?>... attributes) {
    return new State.Builder().define(ruleClassName, attributes);
  }

  /**
   * Returns a new {@link State} for this rule class with arbitrary custom behavior. This is a
   * convenience method for lambda definitions:
   *
   * <pre>
   *   MockRule myRule = () -> MockRule.define(
   *       "my_rule",
   *       (builder, env) -> builder.requiresConfigurationFragments(FooConfiguration.class));
   * </pre>
   */
  static State define(String ruleClassName, MockRuleCustomBehavior customBehavior) {
    return new State.Builder().define(ruleClassName, customBehavior);
  }

  /**
   * Returns the basic state that defines this rule class. This is the only interface method
   * implementers must override.
   */
  State define();

  /**
   * Builds out this rule with default attributes Blaze expects of all rules
   * ({@link MockRuleDefaults#DEFAULT_ATTRIBUTES}) plus the custom attributes defined by this
   * implementation's {@link State}.
   *
   * <p>Do not override this method. For extra custom behavior, use
   * {@link #define(String, MockRuleCustomBehavior)}
   */
  @Override
  default RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
    State state = define();
    if (State.DEFAULT_ANCESTORS.equals(state.ancestors)) {
      MockRuleDefaults.DEFAULT_ATTRIBUTES.stream().forEach(builder::add);
    }
    state.customBehavior.customize(builder, environment);
    return builder.build();
  }

  /**
   * Sets this rule class's metadata with the name defined by {@link State}, configured target
   * factory declared by {@link State.Builder#factory}, and ancestor rule class declared by
   * {@link State.Builder#ancestor}.
   */
  @Override
  default RuleDefinition.Metadata getMetadata() {
    State state = define();
    return RuleDefinition.Metadata.builder()
        .name(state.name)
        .type(state.type)
        .factoryClass(state.factory)
        .ancestors(state.ancestors)
        .build();
  }
}
