/*
 * Copyright 2013-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.android;

import com.facebook.buck.java.AnnotationProcessingParams;
import com.facebook.buck.java.JavacOptions;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.Flavor;
import com.facebook.buck.model.ImmutableFlavor;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleParams;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.BuildRuleType;
import com.facebook.buck.rules.SourcePathResolver;
import com.google.common.base.Optional;
import com.google.common.base.Suppliers;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;

public class AndroidLibraryGraphEnhancer {

  public static enum ResourceDependencyMode {
    FIRST_ORDER,
    TRANSITIVE,
  }

  private static final Flavor DUMMY_R_DOT_JAVA_FLAVOR = ImmutableFlavor.of("dummy_r_dot_java");

  private final BuildTarget dummyRDotJavaBuildTarget;
  private final BuildRuleParams originalBuildRuleParams;
  private final JavacOptions javacOptions;
  private final ResourceDependencyMode resourceDependencyMode;

  public AndroidLibraryGraphEnhancer(
      BuildTarget buildTarget,
      BuildRuleParams buildRuleParams,
      JavacOptions javacOptions,
      ResourceDependencyMode resourceDependencyMode) {
    this.dummyRDotJavaBuildTarget = BuildTarget.builder(buildTarget)
        .addFlavors(DUMMY_R_DOT_JAVA_FLAVOR)
        .build();
    this.originalBuildRuleParams = buildRuleParams;
    // Override javacoptions because DummyRDotJava doesn't require annotation processing.
    this.javacOptions = JavacOptions.builder(javacOptions)
        .setAnnotationProcessingParams(AnnotationProcessingParams.EMPTY)
        .build();
    this.resourceDependencyMode = resourceDependencyMode;
  }

  public Optional<DummyRDotJava> createBuildableForAndroidResources(
      BuildRuleResolver ruleResolver,
      boolean createBuildableIfEmptyDeps) {
    ImmutableSortedSet<BuildRule> originalDeps = originalBuildRuleParams.getDeps();
    ImmutableSet<HasAndroidResourceDeps> androidResourceDeps;

    switch (resourceDependencyMode) {
      case FIRST_ORDER:
        androidResourceDeps = FluentIterable.from(originalDeps)
            .filter(HasAndroidResourceDeps.class)
            .filter(HasAndroidResourceDeps.NON_EMPTY_RESOURCE)
            .toSet();
        break;
      case TRANSITIVE:
        androidResourceDeps = UnsortedAndroidResourceDeps.createFrom(
            originalDeps,
            Optional.<UnsortedAndroidResourceDeps.Callback>absent())
            .getResourceDeps();
        break;
      default:
        throw new IllegalStateException(
            "Invalid resource dependency mode: " + resourceDependencyMode);
    }

    if (androidResourceDeps.isEmpty() && !createBuildableIfEmptyDeps) {
      return Optional.absent();
    }

    // The androidResourceDeps may contain Buildables, but we need the actual BuildRules. Since this
    // is going to be used to modify the build graph, we can't just wrap the buildables. Fortunately
    // we know that the buildables come from the originalDeps.
    ImmutableSortedSet.Builder<BuildRule> actualDeps = ImmutableSortedSet.naturalOrder();
    for (HasAndroidResourceDeps dep : androidResourceDeps) {
      // If this ever returns null, something has gone horrifically awry.
      actualDeps.add(ruleResolver.getRule(dep.getBuildTarget()));
    }

    BuildRuleParams dummyRDotJavaParams = originalBuildRuleParams.copyWithChanges(
        BuildRuleType.DUMMY_R_DOT_JAVA,
        dummyRDotJavaBuildTarget,
        Suppliers.ofInstance(actualDeps.build()),
        /* extraDeps */ Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of()));

    DummyRDotJava dummyRDotJava = new DummyRDotJava(
        dummyRDotJavaParams,
        new SourcePathResolver(ruleResolver),
        androidResourceDeps,
        javacOptions);
    ruleResolver.addToIndex(dummyRDotJava);
    return Optional.of(dummyRDotJava);
  }

}
