/*
 * Copyright 2011 Google 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.google.web.bindery.requestfactory.apt;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.NoType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.type.WildcardType;

/**
 * Uses information in a State object to convert client types to their domain
 * equivalents. This types assumes that any incoming type has already been
 * determined to be a transportable type.
 */
class ClientToDomainMapper extends TypeVisitorBase<TypeMirror> {
  public static class UnmappedTypeException extends RuntimeException {
    private final TypeMirror clientType;

    public UnmappedTypeException() {
      super();
      clientType = null;
    }

    public UnmappedTypeException(TypeMirror clientType) {
      super("No domain type resolved for " + clientType.toString());
      this.clientType = clientType;
    }

    public TypeMirror getClientType() {
      return clientType;
    }
  }

  @Override
  public TypeMirror visitDeclared(DeclaredType x, State state) {
    if (x.asElement().getKind().equals(ElementKind.ENUM)) {
      // Enums map to enums
      return x;
    }
    if (state.types.isAssignable(x, state.entityProxyType)
        || state.types.isAssignable(x, state.valueProxyType)) {
      // FooProxy -> FooDomain
      /*
       * TODO(bobv): This if statement should be widened to baseProxy to support
       * heterogenous collections of any proxy type. The BaseProxy interface
       * would also need to be annotated with an @ProxyFor mapping. This can be
       * done once RFIV is removed, since it only allows homogenous collections.
       */
      TypeElement domainType =
          (TypeElement) state.getClientToDomainMap().get(state.types.asElement(x));
      if (domainType == null) {
        return defaultAction(x, state);
      }
      return domainType.asType();
    }
    if (state.types.isAssignable(x, state.entityProxyIdType)) {
      // EntityProxyId<FooProxy> -> FooDomain
      return convertSingleParamType(x, state.entityProxyIdType, 0, state);
    }
    if (state.types.isAssignable(x, state.requestType)) {
      // Request<FooProxy> -> FooDomain
      return convertSingleParamType(x, state.requestType, 0, state);
    }
    if (state.types.isAssignable(x, state.instanceRequestType)) {
      // InstanceRequest<FooProxy, X> -> FooDomain
      return convertSingleParamType(x, state.instanceRequestType, 1, state);
    }
    for (DeclaredType valueType : getValueTypes(state)) {
      if (state.types.isAssignable(x, valueType)) {
        // Value types map straight through
        return x;
      }
    }
    if (state.types.isAssignable(x, state.findType(List.class))
        || state.types.isAssignable(x, state.findType(Set.class))) {
      // Convert Set,List<FooProxy> to Set,List<FooDomain>
      TypeMirror param = convertSingleParamType(x, state.findType(Collection.class), 0, state);
      return state.types.getDeclaredType((TypeElement) state.types.asElement(x), param);
    }
    final DeclaredType mapType = state.findType(Map.class);
    if (state.types.isAssignable(x, mapType)) {
      // Convert Map<FooProxy, BarProxy> to Map<FooDomain, BarDomain>
      TypeMirror keyParam = convertSingleParamType(x, mapType, 0, state);
      TypeMirror valueParam = convertSingleParamType(x, mapType, 1, state);
      return state.types.getDeclaredType((TypeElement) state.types.asElement(x), keyParam, valueParam);
    }
    return defaultAction(x, state);
  }

  @Override
  public TypeMirror visitNoType(NoType x, State state) {
    if (x.getKind().equals(TypeKind.VOID)) {
      // Pass void through
      return x;
    }
    // Here, x would be NONE or PACKAGE, neither of which make sense
    return defaultAction(x, state);
  }

  @Override
  public TypeMirror visitPrimitive(PrimitiveType x, State state) {
    // Primitives pass through
    return x;
  }

  @Override
  public TypeMirror visitTypeVariable(TypeVariable x, State state) {
    // Convert <T extends FooProxy> to FooDomain
    return x.getUpperBound().accept(this, state);
  }

  @Override
  public TypeMirror visitWildcard(WildcardType x, State state) {
    // Convert <? extends FooProxy> to FooDomain
    return state.types.erasure(x).accept(this, state);
  }

  /**
   * Utility method to convert a {@code Foo<BarProxy> -> BarDomain}. The
   * {@code param} parameter specifies the index of the type paramater to
   * extract.
   */
  protected TypeMirror convertSingleParamType(DeclaredType x, DeclaredType convertTo, int param,
      State state) {
    DeclaredType converted = (DeclaredType) State.viewAs(convertTo, x, state);
    if (converted == null) {
      return state.types.getNoType(TypeKind.NONE);
    }
    if (converted.getTypeArguments().isEmpty()) {
      return defaultAction(x, state);
    }
    return converted.getTypeArguments().get(param).accept(this, state);
  }

  @Override
  protected TypeMirror defaultAction(TypeMirror x, State state) {
    throw new UnmappedTypeException(x);
  }
}
