// 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 com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.packages.RuleClass;
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;

/** <code>j2objc_library</code> rule declaration. */
public class J2ObjcLibraryRule implements RuleDefinition {
  private final J2ObjcAspect j2ObjcAspect;

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

  @Override
  public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
    return builder
        .requiresConfigurationFragments(
            J2ObjcConfiguration.class,
            ObjcConfiguration.class,
            AppleConfiguration.class,
            CppConfiguration.class)
        /* <!-- #BLAZE_RULE(j2objc_library).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).IMPLICIT_OUTPUTS -->
        <ul>
         <li><code><var>name</var>_fully_linked.a</code>: A fully linked static library that
             contains the full transitive closure of transpiled dependencies.</li>
        </ul>
        <!-- #END_BLAZE_RULE.IMPLICIT_OUTPUTS -->*/
        .setImplicitOutputsFunction(CompilationSupport.FULLY_LINKED_LIB)
        .cfg(AppleCrosstoolTransition.APPLE_CROSSTOOL_TRANSITION)
        .addRequiredToolchains(CppRuleClasses.ccToolchainTypeAttribute(env))
        .build();
  }

  @Override
  public Metadata getMetadata() {
    return RuleDefinition.Metadata.builder()
        .name("j2objc_library")
        .factoryClass(J2ObjcLibrary.class)
        .ancestors(
            J2ObjcLibraryBaseRule.class,
            ObjcRuleClasses.CrosstoolRule.class,
            ObjcRuleClasses.LibtoolRule.class,
            ObjcRuleClasses.XcrunRule.class)
        .build();
  }
}

/*<!-- #BLAZE_RULE (NAME = j2objc_library, TYPE = LIBRARY, FAMILY = Objective-C) -->

<p> This rule uses <a href="https://github.com/google/j2objc">J2ObjC</a> to translate Java source
files to Objective-C, which then can be used used as dependencies of objc_library and objc_binary
rules. Detailed information about J2ObjC itself can be found at  <a href="http://j2objc.org">the
J2ObjC site</a>
</p>
<p>Custom J2ObjC transpilation flags can be specified using the build flag
<code>--j2objc_translation_flags</code> in the command line.
</p>
<p>Please note that the translated files included in a j2objc_library target will be
compiled using the default compilation configuration, the same configuration as for the sources of
an objc_library rule with no compilation options specified in attributes.
</p>
<p>Plus, generated code is de-duplicated at target level, not source level. If you have two
different Java targets that include the same Java source files, you may see a duplicate symbol error
at link time. The correct way to resolve this issue is to move the shared Java source files into a
separate common target that can be depended upon.
</p>


<!-- #END_BLAZE_RULE -->*/
