// 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.rules.objc;

import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static com.google.devtools.build.lib.packages.Type.STRING_LIST;

import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.packages.Attribute.ValidityPredicate;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
import com.google.devtools.build.lib.rules.cpp.CppRuleClasses;
import javax.annotation.Nullable;

/**
 * Abstract rule definition for j2objc_library.
 */
public class J2ObjcLibraryBaseRule implements RuleDefinition {
  private final J2ObjcAspect j2ObjcAspect;

  public J2ObjcLibraryBaseRule(J2ObjcAspect j2ObjcAspect) {
    this.j2ObjcAspect = j2ObjcAspect;
  }

  @Override
  public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
    // TODO(rduan): Add support for package prefixes.
    return builder
        .requiresConfigurationFragments(
            AppleConfiguration.class,
            CppConfiguration.class,
            J2ObjcConfiguration.class,
            ObjcConfiguration.class)
        /* <!-- #BLAZE_RULE($j2objc_library_base_rule).ATTRIBUTE(deps) -->
        A list of <code>j2objc_library</code>, <code>java_library</code>,
        <code>java_import</code> and <code>java_proto_library</code> targets that contain
        Java files to be transpiled to Objective-C.
        <p>All <code>java_library</code> and <code>java_import</code> targets that can be reached
        transitively through <code>exports</code>, <code>deps</code> and <code>runtime_deps</code>
        will be translated and compiled. Currently there is no support for files generated by Java
        annotation processing or <code>java_import</code> targets with no <code>srcjar</code>
        specified.
        </p>
        <p>The J2ObjC translation works differently depending on the type of source Java source
        files included in the transitive closure. For each .java source files included in
        <code>srcs</code> of <code>java_library</code>, a corresponding .h and .m source file
        will be generated. For each source jar included in <code>srcs</code> of
        <code>java_library</code> or <code>srcjar</code> of <code>java_import</code>, a
        corresponding .h and .m source file will be generated with all the code for that jar.
        </p>
        <p>Users can import the J2ObjC-generated header files in their code. The import paths for
        these files are the root-relative path of the original Java artifacts. For example,
        <code>//some/package/foo.java</code> has an import path of <code>some/package/foo.h</code>
        and <code>//some/package/bar.srcjar</code> has <code>some/package/bar.h</code
        </p>
        <p>
        If proto_library rules are in the transitive closure of this rule, J2ObjC protos will also
        be generated, compiled and linked-in at the binary level. For proto
        <code>//some/proto/foo.proto</code>, users can reference the generated code using import
        path <code>some/proto/foo.j2objc.pb.h</code>.
        </p>
        <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
        .add(
            attr("deps", LABEL_LIST)
                .aspect(j2ObjcAspect)
                .direct_compile_time_input()
                .allowedRuleClasses(
                    "j2objc_library", "java_library", "java_import", "java_proto_library")
                .allowedFileTypes())
        /* <!-- #BLAZE_RULE($j2objc_library_base_rule).ATTRIBUTE(entry_classes) -->
        The list of Java classes whose translated ObjC counterparts will be referenced directly
        by user ObjC code. This attribute is required if flag <code>--j2objc_dead_code_removal
        </code> is on. The Java classes should be specified in their canonical names as defined by
        <a href="http://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.7">the Java
        Language Specification.</a>
        When flag <code>--j2objc_dead_code_removal</code> is specified, the list of entry classes
        will be collected transitively and used as entry points to perform dead code analysis.
        Unused classes will then be removed from the final ObjC app bundle.
        <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
        .add(attr("entry_classes", STRING_LIST))
        /* <!-- #BLAZE_RULE($j2objc_library_base_rule).ATTRIBUTE(jre_deps) -->
        The list of additional JRE emulation libraries required by all Java code translated by this
        <code>j2objc_library</code> rule. Only core JRE functionality is linked by default.
        <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
        .add(
            attr("jre_deps", LABEL_LIST)
                .direct_compile_time_input()
                .allowedRuleClasses("objc_library")
                .allowedFileTypes()
                .validityPredicate(
                    new ValidityPredicate() {
                      @Override
                      @Nullable
                      public String checkValid(Rule from, Rule to) {
                        if (!to.getRuleTags().contains("j2objc_jre_lib")) {
                          return "Only J2ObjC JRE libraries are allowed";
                        }
                        return null;
                      }
                    }))
        .addToolchainTypes(CppRuleClasses.ccToolchainTypeRequirement(env))
        .build();
  }

  @Override
  public Metadata getMetadata() {
    return RuleDefinition.Metadata.builder()
        .name("$j2objc_library_base_rule")
        .type(RuleClassType.ABSTRACT)
        .ancestors(BaseRuleClasses.NativeBuildRule.class)
        .build();
  }
}

