/*
 * 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.rules;

import com.facebook.buck.model.BuildTarget;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.file.Path;
import java.util.List;
import java.util.Set;

/**
 * Used to derive information from the constructor args returned by {@link Description} instances.
 * There are two major uses this information is put to: populating the DTO object from the
 * {@link BuildRuleFactoryParams}, which is populated by the functions added to Buck's core build
 * file parsing script. The second function of this class is to generate those functions.
 * <p>
 * The constructor arg is examined for public fields and writable properties, as defined by the
 * JavaBean specification. Reflection is used to determine the type of the field, and it's possible
 * to indicate that a field isn't mandatory by using {@link Optional} declarations. If the name of
 * the property to be exposed to a build file does not match the field/bean property name, then a
 * {@link Hint} can be used to set it.
 * <p>
 * As an example, the arguments for a build target defined as:
 * <pre>
 *    example_library(
 *      name = 'example',
 *      srcs = [ '//foo:bar', 'Eggs.java', ],
 *      optional_thing = True,
 *    )
 * </pre>
 * Could be defined as a constructor arg that looks like:
 * <pre>
 *     public class ExampleLibraryArg {
 *       public String name;
 *       public ImmutableSortedSet&gt;SourcePath> srcs;
 *       @Hint(name = "optional_thing")
 *       public Optional&gt;Boolean> isNeeded;
 *     }
 * </pre>
 */
// TODO(simons): Revisit class name when we add Descriptions
public class ArgObjectPopulatomatic {

  private final Path basePath;

  /**
   * Constructor. {@code pathFromProjectRootToBuildFile} is the path relative to the project root to
   * the build file that has called the build rule's function in buck.py. This is used for resolving
   * additional paths to ones relative to the project root, and to allow {@link BuildTarget}
   * instances to be fully qualified.
   *
   * @param pathFromProjectRootToBuildFile The path from the root of the project to the directory of
   *     the build file that this function is being created from.
   */
  public ArgObjectPopulatomatic(Path pathFromProjectRootToBuildFile) {
    Preconditions.checkNotNull(pathFromProjectRootToBuildFile);

    // Without this check an IndexOutOfBounds exception is thrown by normalize.
    if (pathFromProjectRootToBuildFile.toString().isEmpty()) {
      this.basePath = pathFromProjectRootToBuildFile;
    } else {
      this.basePath = pathFromProjectRootToBuildFile.normalize();
    }
  }

  /**
   * Use the information contained in the {@code params} to fill in the public fields and settable
   * properties of {@code dto}. The following rules are used:
   * <ul>
   *   <li>Boolean values are set to true or false.</li>
   *   <li>{@link BuildRule}s will be resovled.</li>
   *   <li>{@link BuildTarget}s are resolved and will be fully qualified.</li>
   *   <li>Numeric values are handled as if being cast from Long.</li>
   *   <li>{@link SourcePath} instances will be set to the appropriate implementation.</li>
   *   <li>{@link Path} declarations will be set to be relative to the project root.</li>
   *   <li>Strings will be set "as is".</li>
   *   <li>{@link List}s and {@link Set}s will be populated with the expected generic type,
   *   provided the wildcarding allows an upperbound to be determined to be one of the above.</li>
   * </ul>
   *
   * Any property that is marked as being an {@link Optional} field will be set to a default value
   * if none is set. This is typically {@link Optional#absent()}, but in the case of collections is
   * an empty collection.
   *
   * @param ruleResolver The resolver to use when looking up {@link BuildRule}s.
   * @param params The parameters to be used to populate the {@code dto} instance.
   * @param dto The constructor dto to be populated.
   */
  public void populate(BuildRuleResolver ruleResolver, BuildRuleFactoryParams params, Object dto) {
    Set<ParamInfo> allInfo = getAllParamInfo(dto);

    for (ParamInfo info : allInfo) {
      info.setFromParams(ruleResolver, dto, params);
    }
  }

  ImmutableSet<ParamInfo> getAllParamInfo(Object dto) {
    Class<?> argClass = dto.getClass();

    ImmutableSet.Builder<ParamInfo> allInfo = ImmutableSet.builder();

    for (Field field : argClass.getFields()) {
      if (Modifier.isFinal(field.getModifiers())) {
        continue;
      }
      allInfo.add(new ParamInfo(basePath, field));
    }

    return allInfo.build();
  }
}
