/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */
/*
 * $Id$
 */

package org.apache.xalan.xsltc.compiler;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Vector;

import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.PUSH;
import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
import org.apache.xalan.xsltc.compiler.util.Type;
import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
import org.apache.xalan.xsltc.compiler.util.Util;

/**
 * @author G. Todd Miller 
 * @author Santiago Pericas-Geertsen
 */
final class FunctionAvailableCall extends FunctionCall {

    private Expression _arg; 
    private String     _nameOfFunct = null; 
    private String     _namespaceOfFunct = null; 	
    private boolean    _isFunctionAvailable = false; 

    /**
     * Constructs a FunctionAvailableCall FunctionCall. Takes the
     * function name qname, for example, 'function-available', and 
     * a list of arguments where the arguments must be instances of 
     * LiteralExpression. 
     */
    public FunctionAvailableCall(QName fname, Vector arguments) {
	super(fname, arguments);
	_arg = (Expression)arguments.elementAt(0);
	_type = null; 

        if (_arg instanceof LiteralExpr) {
	    LiteralExpr arg = (LiteralExpr) _arg;
            _namespaceOfFunct = arg.getNamespace();
            _nameOfFunct = arg.getValue();

            if (!isInternalNamespace()) {
              _isFunctionAvailable = hasMethods();
            }
        }
    }

    /**
     * Argument of function-available call must be literal, typecheck
     * returns the type of function-available to be boolean.  
     */
    public Type typeCheck(SymbolTable stable) throws TypeCheckError {
	if (_type != null) {
	   return _type;
	}
	if (_arg instanceof LiteralExpr) {
	    return _type = Type.Boolean;
	}
	ErrorMsg err = new ErrorMsg(ErrorMsg.NEED_LITERAL_ERR,
			"function-available", this);
	throw new TypeCheckError(err);
    }

    /**
     * Returns an object representing the compile-time evaluation 
     * of an expression. We are only using this for function-available
     * and element-available at this time.
     */
    public Object evaluateAtCompileTime() {
	return getResult() ? Boolean.TRUE : Boolean.FALSE;
    }

    /**
     * for external java functions only: reports on whether or not
     * the specified method is found in the specifed class. 
     */
    private boolean hasMethods() {
	
	// Get the class name from the namespace uri
	String className = getClassNameFromUri(_namespaceOfFunct);
	
	// Get the method name from the argument to function-available
	String methodName = null;
	int colonIndex = _nameOfFunct.indexOf(":");
	if (colonIndex > 0) {
	  String functionName = _nameOfFunct.substring(colonIndex+1);
	  int lastDotIndex = functionName.lastIndexOf('.');
	  if (lastDotIndex > 0) {
	    methodName = functionName.substring(lastDotIndex+1);
	    if (className != null && className.length() != 0)
	      className = className + "." + functionName.substring(0, lastDotIndex);
	    else
	      className = functionName.substring(0, lastDotIndex);
	  }
	  else
	    methodName = functionName;
	}
	else
	  methodName = _nameOfFunct;
	  
	if (className == null || methodName == null) {
	    return false;
	}
	
	// Replace the '-' characters in the method name
	if (methodName.indexOf('-') > 0)
	  methodName = replaceDash(methodName);

	try {
            final Class clazz = ObjectFactory.findProviderClass(
                className, ObjectFactory.findClassLoader(), true);

	    if (clazz == null) {
	    	return false;
	    }

	    final Method[] methods = clazz.getMethods();

	    for (int i = 0; i < methods.length; i++) {
		final int mods = methods[i].getModifiers();

		if (Modifier.isPublic(mods) && Modifier.isStatic(mods)
			&& methods[i].getName().equals(methodName))
		{
		    return true;
		}
	    }
	}
	catch (ClassNotFoundException e) {
	  return false;
	}
        return false;   
    }

    /**
     * Reports on whether the function specified in the argument to
     * xslt function 'function-available' was found.
     */
    public boolean getResult() {
	if (_nameOfFunct == null) { 
	    return false;
	}

        if (isInternalNamespace()) {
            final Parser parser = getParser();
            _isFunctionAvailable = 
		parser.functionSupported(Util.getLocalName(_nameOfFunct));
        }
 	return _isFunctionAvailable;
    }
    
    /**
     * Return true if the namespace uri is null or it is the XSLTC translet uri.
     */
    private boolean isInternalNamespace() {
    	return (_namespaceOfFunct == null ||
            _namespaceOfFunct.equals(EMPTYSTRING) ||
	    _namespaceOfFunct.equals(TRANSLET_URI));
    }

    /**
     * Calls to 'function-available' are resolved at compile time since 
     * the namespaces declared in the stylsheet are not available at run
     * time. Consequently, arguments to this function must be literals.
     */
    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
	final ConstantPoolGen cpg = classGen.getConstantPool();
	methodGen.getInstructionList().append(new PUSH(cpg, getResult()));
    }

}
