/*
 * Copyright 2012-present Facebook, Inc.
 *
 * 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.facebook.buck.java;

import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.parser.AbstractBuildRuleFactory;
import com.facebook.buck.parser.BuildRuleFactoryParams;
import com.facebook.buck.parser.NoSuchBuildTargetException;
import com.facebook.buck.rules.AbstractBuildRuleBuilderParams;
import com.google.common.base.Optional;

import java.util.List;

public class JavaLibraryBuildRuleFactory extends AbstractBuildRuleFactory<DefaultJavaLibraryRule.Builder> {

  public static final String ANNOTATION_PROCESSORS = "annotation_processors";

  @Override
  public DefaultJavaLibraryRule.Builder newBuilder(AbstractBuildRuleBuilderParams params) {
    return DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(params);
  }

  @Override
  protected void amendBuilder(DefaultJavaLibraryRule.Builder builder,
                              BuildRuleFactoryParams params) throws NoSuchBuildTargetException {
    Optional<String> proguardConfig = params.getOptionalStringAttribute("proguard_config");
    builder.setProguardConfig(
        proguardConfig.transform(params.getResolveFilePathRelativeToBuildFileDirectoryTransform()));


    boolean exportDeps = params.getBooleanAttribute("export_deps");
    builder.setExportDeps(exportDeps);

    extractAnnotationProcessorParameters(
        builder.getAnnotationProcessingBuilder(), builder, params);

    Optional<String> sourceLevel = params.getOptionalStringAttribute("source");
    if (sourceLevel.isPresent()) {
      builder.setSourceLevel(sourceLevel.get());
    }

    Optional<String> targetLevel = params.getOptionalStringAttribute("target");
    if (targetLevel.isPresent()) {
      builder.setTargetLevel(targetLevel.get());
    }
  }

  static void extractAnnotationProcessorParameters(
      AnnotationProcessingParams.Builder annotationProcessingBuilder,
      DefaultJavaLibraryRule.Builder buildRuleBuilder,
      BuildRuleFactoryParams params)
      throws NoSuchBuildTargetException {

    // annotation_processors
    //
    // Names of the classes used for annotation processing.  These must be implemented
    // in a BuildTarget listed in annotation_processor_deps.
    List<String> annotationProcessors = params.getOptionalListAttribute(ANNOTATION_PROCESSORS);
    if (!annotationProcessors.isEmpty()) {
      annotationProcessingBuilder.addAllProcessors(annotationProcessors);

      // annotation_processor_deps
      //
      // These are the targets that implement one or more of the annotation_processors.
      for (String processor : params.getOptionalListAttribute("annotation_processor_deps")) {
        BuildTarget buildTarget = params.resolveBuildTarget(processor);
        buildRuleBuilder.addDep(buildTarget);
        annotationProcessingBuilder.addProcessorBuildTarget(buildTarget);
      }

      // annotation_processor_params
      //
      // These will be prefixed with "-A" when passing to javac.  They may be of the
      // form "parameter_name" or "parameter_name=string_value".
      for (String parameter : params.getOptionalListAttribute("annotation_processor_params")) {
        annotationProcessingBuilder.addParameter(parameter);
      }

      // annotation_processor_only
      //
      // If true, we only run annotation processors and do not compile.
      boolean processOnly = params.getBooleanAttribute("annotation_processor_only");
      annotationProcessingBuilder.setProcessOnly(processOnly);
    }
  }
}
