/*
 * Copyright (c) 2010-2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.nashorn.internal.codegen;

import java.lang.invoke.MethodType;
import java.util.Arrays;
import java.util.NoSuchElementException;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.runtime.ScriptFunction;

/**
 * A tuple containing function id, parameter types, return type and needsCallee flag.
 */
public final class TypeMap {
    private final int functionNodeId;
    private final Type[] paramTypes;
    private final Type returnType;
    private final boolean needsCallee;

    /**
     * Constructor
     * @param functionNodeId function node id
     * @param type           method type found at runtime corresponding to parameter guess
     * @param needsCallee    does the function using this type map need a callee
     */
    public TypeMap(final int functionNodeId, final MethodType type, final boolean needsCallee) {
        final Type[] types = new Type[type.parameterCount()];
        int pos = 0;
        for (final Class<?> p : type.parameterArray()) {
            types[pos++] = Type.typeFor(p);
        }

        this.functionNodeId = functionNodeId;
        this.paramTypes = types;
        this.returnType = Type.typeFor(type.returnType());
        this.needsCallee = needsCallee;
    }

    /**
     * Returns the array of parameter types for a particular function node
     * @param functionNodeId the ID of the function node
     * @return an array of parameter types
     * @throws NoSuchElementException if the type map has no mapping for the requested function
     */
    public Type[] getParameterTypes(final int functionNodeId) {
        assert this.functionNodeId == functionNodeId;
        return paramTypes.clone();
    }

    MethodType getCallSiteType(final FunctionNode functionNode) {
        assert this.functionNodeId == functionNode.getId();
        final Type[] types = paramTypes;
        MethodType mt = MethodType.methodType(returnType.getTypeClass());
        if (needsCallee) {
            mt = mt.appendParameterTypes(ScriptFunction.class);
        }

        mt = mt.appendParameterTypes(Object.class); //this

        for (final Type type : types) {
            if (type == null) {
                return null; // not all parameter information is supplied
            }
            mt = mt.appendParameterTypes(type.getTypeClass());
        }

        return mt;
    }

    /**
     * Does the function using this TypeMap need a callee argument. This is used
     * to compute correct param index offsets in {@link jdk.nashorn.internal.codegen.ApplySpecialization}
     * @return true if a callee is needed, false otherwise
     */
    public boolean needsCallee() {
        return needsCallee;
    }

    /**
     * Get the parameter type for this parameter position, or
     * null if now known
     * @param functionNode functionNode
     * @param pos position
     * @return parameter type for this callsite if known
     */
    Type get(final FunctionNode functionNode, final int pos) {
        assert this.functionNodeId == functionNode.getId();
        final Type[] types = paramTypes;
        assert types == null || pos < types.length : "fn = " + functionNode.getId() + " " + "types=" + Arrays.toString(types) + " || pos=" + pos + " >= length=" + types.length + " in " + this;
        if (types != null && pos < types.length) {
            return types[pos];
        }
        return null;
    }

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

    String toString(final String prefix) {
        final StringBuilder sb = new StringBuilder();

        final int id = functionNodeId;
        sb.append(prefix).append('\t');
        sb.append("function ").append(id).append('\n');
        sb.append(prefix).append("\t\tparamTypes=");
        sb.append(Arrays.toString(paramTypes));
        sb.append('\n');
        sb.append(prefix).append("\t\treturnType=");
        final Type ret = returnType;
        sb.append(ret == null ? "N/A" : ret);
        sb.append('\n');

        return sb.toString();
    }
}
