/*
 * Copyright 2014-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.model.BuildTarget;
import com.facebook.buck.rules.coercer.BuildConfigFields;
import com.facebook.buck.rules.coercer.ImmutableBuildConfigFields;
import com.google.common.collect.ImmutableList;

/**
 * Utilities for generating a {@code BuildConfig.java} file for Android.
 */
public class BuildConfigs {

  /**
   * Name of the boolean global variable provided by the standard Android tools to indicate whether
   * an app was built in debug mode or not.
   */
  public static final String DEBUG_CONSTANT = "DEBUG";

  /**
   * Name of a Buck-specific global variable that indicates whether an app was built using
   * exopackage.
   */
  public static final String IS_EXO_CONSTANT = "IS_EXOPACKAGE";

  /**
   * Name of a global variable that includes the exopackage configuration as a bitmask.
   */
  public static final String EXOPACKAGE_FLAGS = "EXOPACKAGE_FLAGS";

  /** @see #getDefaultBuildConfigFields() */
  private static final BuildConfigFields DEFAULT_BUILD_CONFIG_CONSTANTS =
      BuildConfigFields.fromFields(ImmutableList.<BuildConfigFields.Field>of(
              // DEBUG is expected by the standard Android tools.
              ImmutableBuildConfigFields.Field.of("boolean", DEBUG_CONSTANT, "true"),
              // IS_EXOPACKAGE is a value we use internally for checking whether exopackage is being
              // used.
              ImmutableBuildConfigFields.Field.of("boolean", IS_EXO_CONSTANT, "false"),
              ImmutableBuildConfigFields.Field.of("int", EXOPACKAGE_FLAGS, "0")));

  /** Utility class: do not instantiate. */
  private BuildConfigs() {}

  /**
   * Returns a list of fields (with values) that every {@code BuildConfig.java} should
   * declare. The default value of each constant may be overridden by the {@code userFields} passed
   * to {@link #generateBuildConfigDotJava(BuildTarget, String, boolean, BuildConfigFields)} when
   * generating a {@code BuildConfig.java}.
   */
  public static BuildConfigFields getDefaultBuildConfigFields() {
    return DEFAULT_BUILD_CONFIG_CONSTANTS;
  }

  /**
   * Generates the source code for an Android {@code BuildConfig.java} file with the default set of
   * fields specified by {@link #getDefaultBuildConfigFields()}.
   */
  public static String generateBuildConfigDotJava(BuildTarget source, String javaPackage) {
    return generateBuildConfigDotJava(
        source,
        javaPackage,
        /* useConstantExpressions */ false,
        BuildConfigFields.empty());
  }

  /**
   * Generates the source code for an Android {@code BuildConfig.java} file with fields
   * specified by {@code userFields}.
   * <p>
   * The output will also contain a constant for every entry in the collection returned by
   * {@link #getDefaultBuildConfigFields()}.
   * <p>
   * If the name of a field in {@code userFields} matches one in the collection returned by
   * {@link #getDefaultBuildConfigFields()}, the value in the {@code userFields} map will be
   * used.
   * @param javaPackage The package for the Java class generated by this method.
   * @param useConstantExpressions If {@code true}, the value for each static final field in the
   *     generated class will be declared as the literal value in {@code userFields}. The
   *     values of such fields can be inlined by {@code javac}.
   *     <p>
   *     If {@code false}, the value for each static final field in the generated class will be
   *     declared as a non-constant expression that is guaranteed to evaluate to the same value
   *     in {@code userFields}. This ensures that the generated {@code BuildConfig.java}
   *     can still be used in Robolectric tests, but does not run the risk of its values being
   *     inlined by {@code javac}. This is important if the generated {@code BuildConfig} class is
   *     going to be swapped out by a different implementation by {@link AndroidBinary}. See
   *     {@link AndroidBuildConfig} for details.
   * @param userFields represents the fields that should be declared in the generated
   *     {@code BuildConfig} class.
   */
  public static String generateBuildConfigDotJava(
      BuildTarget source,
      String javaPackage,
      boolean useConstantExpressions,
      BuildConfigFields userFields) {

    BuildConfigFields totalFields = getDefaultBuildConfigFields().putAll(userFields);
    return totalFields.generateBuildConfigDotJava(source, javaPackage, useConstantExpressions);
  }
}
