/*
 * Copyright 2009 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.gwt.uibinder.rebind;

import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;

import java.util.LinkedHashSet;

/**
 * Represents a <code>{field.reference}</code>. Collects all the types a
 * particular reference has been asked to return, and can validate that it
 * actually does so.
 */
public class FieldReference {
  private final FieldManager fieldManager;

  private final String debugString;
  private final String[] elements;
  private final LinkedHashSet<JType> leftHandTypes = new LinkedHashSet<JType>();

  private final TypeOracle types;

  FieldReference(String reference, FieldManager fieldManager, TypeOracle types) {
    this.debugString = "{" + reference + "}";
    this.fieldManager = fieldManager;
    this.types = types;
    elements = reference.split("\\.");
  }

  public void addLeftHandType(JType type) {
    leftHandTypes.add(type);
  }

  public String getFieldName() {
    return elements[0];
  }

  @Override
  public String toString() {
    return debugString;
  }

  public void validate(MonitoredLogger logger) {
    JType myReturnType = findReturnType(logger);
    if (myReturnType == null) {
      return;
    }

    for (JType t : leftHandTypes) {
      ensureAssignable(t, myReturnType, logger);
    }
  }

  /**
   * Returns a failure message if the types don't mesh, or null on success.
   */
  private void ensureAssignable(JType leftHandType, JType rightHandType,
      MonitoredLogger logger) {

    if (leftHandType == rightHandType) {
      return;
    }

    if (handleMismatchedNumbers(leftHandType, rightHandType)) {
      return;
    }

    if (handleMismatchedNonNumericPrimitives(leftHandType, rightHandType,
        logger)) {
      return;
    }

    JClassType leftClass = leftHandType.isClassOrInterface();
    if (leftClass != null) {
      JClassType rightClass = rightHandType.isClassOrInterface();
      if ((rightClass == null) || !leftClass.isAssignableFrom(rightClass)) {
        logTypeMismatch(leftHandType, rightHandType, logger);
      }
    }

    /*
     * We're conservative and fall through here, allowing success. Not yet
     * confident that we know every error case, and are more worried about being
     * artificially restrictive.
     */
  }

  private JType findReturnType(MonitoredLogger logger) {
    FieldWriter field = fieldManager.lookup(elements[0]);
    if (field == null) {
      logger.error("No field named %s", elements[0]);
      return null;
    }

    return field.getReturnType(elements, logger);
  }

  private boolean handleMismatchedNonNumericPrimitives(JType leftHandType,
      JType rightHandType, MonitoredLogger logger) {
    JPrimitiveType leftPrimitive = leftHandType.isPrimitive();
    JPrimitiveType rightPrimitive = rightHandType.isPrimitive();

    if (leftPrimitive == null && rightPrimitive == null) {
      return false;
    }

    if (leftPrimitive != null) {
      JClassType autobox = types.findType(leftPrimitive.getQualifiedBoxedSourceName());
      if (rightHandType != autobox) {
        logger.error("Returns %s, can't be used as %s", rightHandType,
            leftHandType);
      }
    } else { // rightPrimitive != null
      JClassType autobox = types.findType(rightPrimitive.getQualifiedBoxedSourceName());
      if (leftHandType != autobox) {
        logger.error("Returns %s, can't be used as %s", rightHandType,
            leftHandType);
      }
    }

    return true;
  }

  private boolean handleMismatchedNumbers(JType leftHandType,
      JType rightHandType) {
    /*
     * int i = (int) 1.0 is okay
     * Integer i = (int) 1.0 is okay
     * int i = (int) Double.valueOf(1.0) is not
     */
    if (isNumber(leftHandType) && isNumber(rightHandType)
        && (rightHandType.isPrimitive() != null)) {
      return true; // They will be cast into submission
    }

    return false;
  }

  private boolean isNumber(JType t) {
    JClassType numberType = types.findType(Number.class.getCanonicalName());

    JClassType asClass = t.isClass();
    if (asClass != null) {
      return numberType.isAssignableFrom(asClass);
    }

    JPrimitiveType asPrimitive = t.isPrimitive();
    if (asPrimitive != null) {
      JClassType autoboxed = types.findType(asPrimitive.getQualifiedBoxedSourceName());
      return numberType.isAssignableFrom(autoboxed);
    }

    return false;
  }

  private void logTypeMismatch(JType leftHandType, JType rightHandType,
      MonitoredLogger logger) {
    logger.error("Returns %s, can't be used as %s", rightHandType, leftHandType);
  }
}
