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

import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetPattern;
import com.facebook.buck.model.Pair;
import com.facebook.buck.parser.BuildTargetParser;
import com.facebook.buck.rules.Label;
import com.facebook.buck.rules.SourcePath;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.primitives.Primitives;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.nio.file.Path;

/**
 * Create {@link TypeCoercer}s that can convert incoming java structures (from json) into particular
 * types.
 */
public class TypeCoercerFactory {
  private final TypeCoercer<Label> labelTypeCoercer = new LabelTypeCoercer();
  private final TypeCoercer<Path> pathTypeCoercer = new PathTypeCoercer();
  private final TypeCoercer<BuildTarget> buildTargetTypeCoercer;
  private final TypeCoercer<SourcePath> sourcePathTypeCoercer;

  // This has no implementation, but is here so that constructor succeeds so that it can be queried.
  // This is only used for the visibility field, which is not actually handled by the coercer.
  private final TypeCoercer<BuildTargetPattern> buildTargetPatternTypeCoercer =
      new IdentityTypeCoercer<BuildTargetPattern>(BuildTargetPattern.class) {
        @Override
        public BuildTargetPattern coerce(
            BuildTargetParser buildTargetParser,
            ProjectFilesystem filesystem,
            Path pathRelativeToProjectRoot,
            Object object)
            throws CoerceFailedException {
          throw new UnsupportedOperationException();
        }
      };

  private final TypeCoercer<String> stringTypeCoercer = new IdentityTypeCoercer<>(String.class);

  private final TypeCoercer<SourceWithFlags> sourceWithFlagsTypeCoercer;

  private final TypeCoercer<OCamlSource> ocamlSourceTypeCoercer;

  private final TypeCoercer<?>[] nonContainerTypeCoercers;

  public TypeCoercerFactory() {
    buildTargetTypeCoercer = new BuildTargetTypeCoercer();
    sourcePathTypeCoercer = new SourcePathTypeCoercer(buildTargetTypeCoercer, pathTypeCoercer);
    sourceWithFlagsTypeCoercer = new SourceWithFlagsTypeCoercer(
        sourcePathTypeCoercer,
        new ListTypeCoercer<>(stringTypeCoercer));
    ocamlSourceTypeCoercer = new OCamlSourceTypeCoercer(sourcePathTypeCoercer);
    nonContainerTypeCoercers = new TypeCoercer<?>[] {
        // special classes
        labelTypeCoercer,
        pathTypeCoercer,
        sourcePathTypeCoercer,
        buildTargetTypeCoercer,
        buildTargetPatternTypeCoercer,

        // identity
        stringTypeCoercer,
        new IdentityTypeCoercer<>(Boolean.class),

        // numeric
        new NumberTypeCoercer<>(Integer.class),
        new NumberTypeCoercer<>(Double.class),
        new NumberTypeCoercer<>(Float.class),
        new NumberTypeCoercer<>(Long.class),
        new NumberTypeCoercer<>(Short.class),
        new NumberTypeCoercer<>(Byte.class),

        // other simple
        sourceWithFlagsTypeCoercer,
        ocamlSourceTypeCoercer,
        new AppleBundleDestinationTypeCoercer(stringTypeCoercer),
        new BuildConfigFieldsTypeCoercer(),
        new UriTypeCoercer(),
    };
  }

  public TypeCoercer<?> typeCoercerForType(Type type) {
    if (type instanceof TypeVariable) {
      type = ((TypeVariable<?>) type).getBounds()[0];
      if (Object.class.equals(type)) {
        throw new IllegalArgumentException("Generic types must be specific: " + type);
      }
    }

    if (type instanceof WildcardType) {
      type = ((WildcardType) type).getUpperBounds()[0];
      if (Object.class.equals(type)) {
        throw new IllegalArgumentException("Generic types must be specific: " + type);
      }
    }

    if (type instanceof Class) {
      Class<?> rawClass = Primitives.wrap((Class<?>) type);

      if (rawClass.isEnum()) {
        return new EnumTypeCoercer<>(rawClass);
      }

      TypeCoercer<?> selectedTypeCoercer = null;
      for (TypeCoercer<?> typeCoercer : nonContainerTypeCoercers) {
        if (rawClass.isAssignableFrom(typeCoercer.getOutputClass())) {
          if (selectedTypeCoercer == null) {
            selectedTypeCoercer = typeCoercer;
          } else {
            throw new IllegalArgumentException("multiple coercers matched for type: " + type);
          }
        }
      }
      if (selectedTypeCoercer != null) {
        return selectedTypeCoercer;
      } else {
        throw new IllegalArgumentException("no type coercer for type: " + type);
      }
    } else if (type instanceof ParameterizedType) {
      ParameterizedType parameterizedType = (ParameterizedType) type;

      Type rawType = parameterizedType.getRawType();
      if (!(rawType instanceof Class<?>)) {
        throw new RuntimeException(
            "expected getRawType() to return a class for type: " + parameterizedType);
      }

      Class<?> rawClass = (Class<?>) rawType;
      if (rawClass.equals(Either.class)) {
        Preconditions.checkState(parameterizedType.getActualTypeArguments().length == 2,
            "expected type '%s' to have two parameters", parameterizedType);
        return new EitherTypeCoercer<>(
            typeCoercerForType(parameterizedType.getActualTypeArguments()[0]),
            typeCoercerForType(parameterizedType.getActualTypeArguments()[1]));
      } else if (rawClass.equals(Pair.class)) {
        Preconditions.checkState(parameterizedType.getActualTypeArguments().length == 2,
            "expected type '%s' to have two parameters", parameterizedType);
        return new PairTypeCoercer<>(
            typeCoercerForType(parameterizedType.getActualTypeArguments()[0]),
            typeCoercerForType(parameterizedType.getActualTypeArguments()[1]));
      } else if (rawClass.isAssignableFrom(ImmutableList.class)) {
        return new ListTypeCoercer<>(
            typeCoercerForType(getSingletonTypeParameter(parameterizedType)));
      } else if (rawClass.isAssignableFrom(ImmutableSet.class)) {
        return new SetTypeCoercer<>(
            typeCoercerForType(getSingletonTypeParameter(parameterizedType)));
      } else if (rawClass.isAssignableFrom(ImmutableSortedSet.class)) {
        // SortedSet is tested second because it is a subclass of Set, and therefore can
        // be assigned to something of type Set, but not vice versa.
        Type elementType = getSingletonTypeParameter(parameterizedType);
        @SuppressWarnings({"rawtypes", "unchecked"})
        SortedSetTypeCoercer<?> sortedSetTypeCoercer = new SortedSetTypeCoercer(
            typeCoercerForComparableType(elementType));
        return sortedSetTypeCoercer;
      } else if (rawClass.isAssignableFrom(ImmutableMap.class)) {
        Preconditions.checkState(parameterizedType.getActualTypeArguments().length == 2,
            "expected type '%s' to have two parameters", parameterizedType);
        return new MapTypeCoercer<>(
            typeCoercerForType(parameterizedType.getActualTypeArguments()[0]),
            typeCoercerForType(parameterizedType.getActualTypeArguments()[1]));
      } else if (rawClass.isAssignableFrom(ImmutableSortedMap.class)) {
        Preconditions.checkState(parameterizedType.getActualTypeArguments().length == 2,
            "expected type '%s' to have two parameters", parameterizedType);
        @SuppressWarnings({"rawtypes", "unchecked"})
        SortedMapTypeCoercer<?, ?> sortedMapTypeCoercer = new SortedMapTypeCoercer(
            typeCoercerForComparableType(parameterizedType.getActualTypeArguments()[0]),
            typeCoercerForType(parameterizedType.getActualTypeArguments()[1]));
        return sortedMapTypeCoercer;
      } else {
        throw new IllegalArgumentException("Unhandled type: " + type);
      }
    } else {
      throw new IllegalArgumentException("Cannot create type coercer for type: " + type);
    }
  }

  private <T extends Comparable<T>> TypeCoercer<T> typeCoercerForComparableType(Type type) {
    Preconditions.checkState(
        type instanceof Class && Comparable.class.isAssignableFrom((Class<?>) type),
        "type '%s' should be a class implementing Comparable",
        type);

    @SuppressWarnings("unchecked")
    TypeCoercer<T> typeCoercer = (TypeCoercer<T>) typeCoercerForType(type);
    return typeCoercer;
  }

  private static Type getSingletonTypeParameter(ParameterizedType type) {
    Preconditions.checkState(type.getActualTypeArguments().length == 1,
        "expected type '%s' to have one parameter", type);
    return type.getActualTypeArguments()[0];
  }
}
