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

/**
 * 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
                      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();
  }
}

