/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Cameron Bateman/Oracle - initial API and implementation
 *    
 ********************************************************************************/

package org.eclipse.jst.jsf.common.internal.types;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.jdt.core.Signature;

/**
 * Static utility class used to compare two CompositeTypes for compatability
 * 
 * @author cbateman
 * 
 */
public final class TypeComparator {
    private static class SignatureTestResult {
        /**
         * the diagnostic
         */
        private final Diagnostic diagnostic;
        /**
         * Measure of the probability that the tested signatures were meant to
         * match. Larger value means higher probability.
         */
        private final int matchQuality;

        /**
         * @param diagnostic
         * @param matchQuality -
         *            Measure of the probability that the tested signatures were
         *            meant to match. Larger value means higher probability.
         */
        public SignatureTestResult(final Diagnostic diagnostic,
                final int matchQuality) {
            super();
            this.diagnostic = diagnostic;
            this.matchQuality = matchQuality;
        }
    }

    private final TypeComparatorDiagnosticFactory   _factory;

    /**
     * Default Constructor
     * @param factory 
     */
    public TypeComparator(final TypeComparatorDiagnosticFactory factory) 
    {
        _factory = factory;
    }

    /**
     * @param firstType
     * @param secondType
     * @return true if firstType is assignable to secondType or vice-versa,
     *         depending on their assignment and runtime types
     */
    public Diagnostic calculateTypeCompatibility(
            final CompositeType firstType, final CompositeType secondType) {
        // first, box all primitives
        final CompositeType boxedFirstType = TypeTransformer
                .transformBoxPrimitives(firstType);
        final CompositeType boxedSecondType = TypeTransformer
                .transformBoxPrimitives(secondType);

        final String[] mustBeSatisfied = boxedFirstType.getSignatures();
        final String[] testSignatures = boxedSecondType.getSignatures();
        List<String> mustbeMethods = Collections.emptyList();
        List<String> mustbeTypes = Collections.emptyList();
        for (final String mustbeSignature : mustBeSatisfied) {
            if (TypeUtil.isMethodSignature(mustbeSignature)) {
                if (mustbeMethods.isEmpty()) {
                    mustbeMethods = new ArrayList<String>(mustbeSignature
                            .length());
                }
                mustbeMethods.add(mustbeSignature);
            } else {
                if (mustbeTypes.isEmpty()) {
                    mustbeTypes = new ArrayList<String>(mustbeSignature
                            .length());
                }
                mustbeTypes.add(mustbeSignature);
            }
        }
        final boolean mustbeWriteable = firstType.isLHS();
        SignatureTestResult bestResult = null;
        for (final String isSignature : testSignatures) {
            SignatureTestResult testResult;
            if (TypeUtil.isMethodSignature(isSignature)) {
                testResult = checkMethodSignature(isSignature, mustbeTypes,
                        mustbeMethods);
                if (testResult.diagnostic.getSeverity() == Diagnostic.OK) {
                    return testResult.diagnostic;
                }
            } else {
                testResult = checkTypeSignature(isSignature, mustbeTypes,
                        mustbeMethods, mustbeWriteable);
                if (testResult.diagnostic.getSeverity() == Diagnostic.OK) {
                    return checkAssignability(firstType, secondType);
                }
            }
            if (bestResult == null
                    || bestResult.matchQuality < testResult.matchQuality) {
                bestResult = testResult;
            }
        }
        // TODO: bestResult empty? (should not happen, but who knows...
        return bestResult.diagnostic;
    }

    private SignatureTestResult checkTypeSignature(
            final String isSignature, final List<String> mustbeTypes,
            final List<String> mustbeMethods, final boolean mustbeWriteable) {
        if (mustbeTypes.isEmpty()) {
            final Diagnostic diag = _factory.create_METHOD_EXPRESSION_EXPECTED();
            return new SignatureTestResult(diag, 0);
        }
        for (final String mustbeSignature : mustbeTypes) {
            if (mustbeSignature.equals(isSignature)
                    || canCoerce(isSignature, mustbeSignature, mustbeWriteable)) {
                final Diagnostic diag = Diagnostic.OK_INSTANCE;
                return new SignatureTestResult(diag, 5);
            }
        }
        final String[] params = new String[2];
        params[0] = readableSignatures(mustbeTypes);
        params[1] = Signature.toString(isSignature);
        final Diagnostic diag = _factory.create_INCOMPATIBLE_TYPES(params);
        return new SignatureTestResult(diag, 1);
    }

    private SignatureTestResult checkMethodSignature(
            final String isSignature, final List<String> mustbeTypes,
            final List<String> mustbeMethods) {
        if (mustbeMethods.isEmpty()) {
            final Diagnostic diag = _factory.create_VALUE_EXPRESSION_EXPECTED();
            return new SignatureTestResult(diag, 0);
        }
        for (final String mustbeSignature : mustbeMethods) {
            if (methodSignaturesMatch(mustbeSignature, isSignature)) {
                final Diagnostic diag = Diagnostic.OK_INSTANCE;
                return new SignatureTestResult(diag, 5);
            }
        }
        final String[] params = new String[2];
        params[0] = readableSignatures(mustbeMethods);
        params[1] = Signature
                .toString(isSignature, "method", null, false, true); //$NON-NLS-1$
        final Diagnostic diag = _factory.create_INCOMPATIBLE_METHOD_TYPES(params);
        return new SignatureTestResult(diag, 1);
    }

    private static String readableSignatures(final List<String> signatures) {
        StringBuilder res = null;
        for (final String sig : signatures) {
            String sigText;
            if (TypeUtil.isMethodSignature(sig)) {
                sigText = Signature.toString(sig, "method", null, false, true); //$NON-NLS-1$
            } else {
                sigText = Signature.toString(sig);
            }
            if (res == null) {
                res = new StringBuilder(sigText);
            } else {
                res.append(", ").append(sigText); //$NON-NLS-1$
            }
        }
        return res != null ? res.toString() : "[no signature]"; //$NON-NLS-1$
    }

    private static boolean canCoerce(final String testType,
            final String checkType, final boolean checkTypeIsWritable) {
        boolean canCoerce = canCoerce(testType, checkType);

        // if the check type is writable, we need to be sure that the
        // coercion can work in both directions
        if (canCoerce && checkTypeIsWritable) {
            // reverse roles: can checkType assign back to test type?
            canCoerce &= canCoerce(checkType, testType);
        }

        return canCoerce;
    }

    private static boolean canCoerce(final String testType,
            final String checkType) {
        // can always to coerce to string or object
        if (TypeCoercer.typeIsString(checkType)
                || TypeConstants.TYPE_JAVAOBJECT.equals(checkType)) 
        {
            return true;
        } else if (TypeCoercer.typeIsNumeric(checkType)) {
            return canCoerceNumeric(testType);
        } else if (TypeCoercer.typeIsBoolean(checkType)) {
            return TypeCoercer.canCoerceToBoolean(testType);
        }

        // otherwise, no type coercion available
        return false;
    }

    private static boolean canCoerceNumeric(final String testType) {
        try {
            TypeCoercer.coerceToNumber(testType);
            // TODO: there is a case when coerceToNumber returns
            // null meaning "not sure", that we may want to handle
            // differently, with a warning
            return true;
        } catch (final TypeCoercionException tce) {
            // outright failure -- can't coerce
            return false;
        }
    }

    private static boolean methodSignaturesMatch(final String firstMethodSig,
            final String secondMethodSig) {
        // TODO: need to account for primitive type coercions
        if (firstMethodSig.equals(secondMethodSig)) {
            return true;
        }
        final String[] firstMethodParams = Signature
                .getParameterTypes(firstMethodSig);
        final String[] secondMethodParams = Signature
                .getParameterTypes(secondMethodSig);

        // fail fast if param count doesn't match
        if (firstMethodParams.length != secondMethodParams.length) {
            return false;
        }

        // now check each parameter
        for (int i = 0; i < firstMethodParams.length; i++) {
            // need to box primitives before comparing
            final String firstMethodParam = TypeTransformer
                    .transformBoxPrimitives(firstMethodParams[i]);
            final String secondMethodParam = TypeTransformer
                    .transformBoxPrimitives(secondMethodParams[i]);

            if (!firstMethodParam.equals(secondMethodParam)) {
                return false;
            }
        }

        // if we get to here then we need only check the return type
        final String firstReturn = TypeTransformer
                .transformBoxPrimitives(Signature.getReturnType(firstMethodSig));
        final String secondReturn = TypeTransformer
                .transformBoxPrimitives(Signature
                        .getReturnType(secondMethodSig));

        if (!firstReturn.equals(secondReturn)) {
            return false;
        }

        // if we get to here, then everything checks out
        return true;
    }

    /**
     * Precond: both firstType and secondType must represent value bindings.
     * 
     * @param firstType
     * @param secondType
     * @return a diagnostic validating that the two composite have compatible
     *         assignability
     */
    private Diagnostic checkAssignability(final CompositeType firstType,
            final CompositeType secondType) {
        if (firstType.isRHS() && !secondType.isRHS()) {
            return _factory.create_PROPERTY_NOT_READABLE();
        }

        if (firstType.isLHS() && !secondType.isLHS()) {
            return _factory.create_PROPERTY_NOT_WRITABLE();
        }

        return Diagnostic.OK_INSTANCE;
    }
}
