/*
 * $Id$
 * 
 * Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
 * 
 * Redistribution and use of this software and associated documentation
 * ("Software"), with or without modification, are permitted provided that the
 * following conditions are met:
 *  1. Redistributions of source code must retain copyright statements and
 * notices. Redistributions must also contain a copy of this document.
 *  2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *  3. The name "groovy" must not be used to endorse or promote products
 * derived from this Software without prior written permission of The Codehaus.
 * For written permission, please contact info@codehaus.org.
 *  4. Products derived from this Software may not be called "groovy" nor may
 * "groovy" appear in their names without prior written permission of The
 * Codehaus. "groovy" is a registered trademark of The Codehaus.
 *  5. Due credit should be given to The Codehaus - http://groovy.codehaus.org/
 * 
 * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *  
 */

package org.codehaus.groovy.runtime;

import groovy.lang.GString;
import groovy.lang.GroovyRuntimeException;
import groovy.lang.IntRange;
import groovy.util.GroovyTestCase;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import junit.framework.AssertionFailedError;

/**
 * Tests method invocation
 * 
 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
 * @version $Revision$
 */
public class InvokeMethodTest extends GroovyTestCase {

    protected Invoker invoker = new Invoker();

    // Method invocation tests
    //-------------------------------------------------------------------------

    public void testInvokeMethodNoParams() throws Throwable {
        Object value = invoke(this, "mockCallWithNoParams", null);
        assertEquals("return value", "NoParams", value);

        value = invoke(this, "mockCallWithNoParams", new Object[0]);
        assertEquals("return value", "NoParams", value);
    }

    public void testInvokeMethodOneParam() throws Throwable {
        Object value = invoke(this, "mockCallWithOneParam", "abc");
        assertEquals("return value", "OneParam", value);
    }

    public void testInvokeMethodOneParamWhichIsNull() throws Throwable {
        Object value = invoke(this, "mockCallWithOneNullParam", new Object[] { null });
        assertEquals("return value", "OneParamWithNull", value);

        value = invoke(this, "mockCallWithOneNullParam", null);
        assertEquals("return value", "OneParamWithNull", value);
    }

    public void testInvokeOverloadedMethodWithOneParamWhichIsNull() throws Throwable {
        Object value = invoke(this, "mockOverloadedMethod", new Object[] { null });
        assertEquals("return value", "Object", value);
    }

    public void testInvokeMethodOneCollectionParameter() throws Throwable {
        Object[] foo = { "a", "b", "c" };

        Object value = invoke(this, "mockCallWithOneCollectionParam", new Object[] { foo });
        assertEquals("return value", new Integer(3), value);

        List list = new ArrayList();
        list.add("a");
        list.add("b");
        value = invoke(this, "mockCallWithOneCollectionParam", list);
        assertEquals("return value", new Integer(2), value);
    }

    public void testInvokePrintlnMethod() throws Throwable {
        Object value = invoke(System.out, "println", "testing System.out.println...");
        assertEquals("return value", null, value);
    }

    public void testMethodChooserNull() throws Throwable {
        assertMethodChooser("Object", new Object[] { null });
    }

    public void testMethodChooserNoParams() throws Throwable {
        assertMethodChooser("void", null);
    }

    public void testMethodChooserObject() throws Throwable {
        assertMethodChooser("Object", new Object());
        assertMethodChooser("Object", new Date());
    }

    public void testMethodChooserString() throws Throwable {
        assertMethodChooser("String", "foo");

        /** @todo some type cooercion would be cool here... */
        //assertMethodChooser("String", new StringBuffer());
        //assertMethodChooser("String", new Character('a');
    }

    public void testMethodChooserNumber() throws Throwable {
        assertMethodChooser("Number", new Integer(2));
        assertMethodChooser("Number", new Double(2));
    }

    public void testMethodChooserTwoParams() throws Throwable {
        List list = new ArrayList();
        list.add("foo");
        list.add("bar");
        assertMethodChooser("Object,Object", list.toArray());

        Object[] blah = { "a", "b" };
        assertMethodChooser("Object,Object", blah);
    }

    public void testInstanceofWorksForArray() {
        Class type = Object[].class;
        Object value = new Object[1];
        assertTrue("instanceof works for array", type.isInstance(value));
    }

    public void testMethodChooserTwoParamsWithSecondAnObjectArray() throws Throwable {
        Object[] blah = { "a", new Object[] { "b" }
        };
        assertMethodChooser("Object,Object[]", blah);
    }

    public void testCollectionMethods() throws Throwable {
        Object list = InvokerHelper.createList(new Object[] { "a", "b" });

        Object value = invoke(list, "size", null);
        assertEquals("size of collection", new Integer(2), value);

        value = invoke(list, "contains", "a");
        assertEquals("contains method", Boolean.TRUE, value);
    }

    public void testNewMethods() throws Throwable {
        Object value = invoke("hello", "size", null);
        assertEquals("size of string", new Integer(5), value);
    }

    public void testStaticMethod() throws Throwable {
        Object value = invoke(DummyBean.class, "dummyStaticMethod", "abc");
        assertEquals("size of string", "ABC", value);
    }

    public void testBaseClassMethod() throws Throwable {
        Object object = new DummyBean();
        Object value = invoke(object, "toString", null);
        assertEquals("toString", object.toString(), value);
    }

	//SPG modified to reflect DefaultGroovyMethod name change and expected result from
	//Integer/Integer division.
    public void testDivideNumbers() throws Throwable {
        assertMethodCall(new Double(10), "div", new Double(2), new Double(5));
        assertMethodCall(new Double(10), "div", new Integer(2), new Double(5));
        assertMethodCall(new Integer(10), "div", new Double(2), new Double(5));
        assertMethodCall(new Integer(10), "div", new Integer(2), new java.math.BigDecimal("5"));
    }

    public void testBaseFailMethod() throws Throwable {
        Object value;
        try {
            value = invoke(this, "fail", "hello");
        }
        catch (AssertionFailedError e) {
            // worked
        }
    }

    public void testToArrayOnList() throws Throwable {
        List object = new ArrayList();
        object.add("Hello");

        Object[] value = (Object[]) invoke(object, "toArray", null);
        assertArrayEquals(object.toArray(), value);
        assertEquals(1, value.length);
        assertEquals("Hello", value[0]);

        value = (Object[]) invoke(object, "toArray", new Object[0]);
        assertArrayEquals(object.toArray(), value);
    }

    public void testInvalidOverloading() throws Throwable {
        try {
            invoke(this, "badOverload", new Object[] { "a", "b" });
            fail("Should fail as an unambiguous method is invoked");
        }
        catch (GroovyRuntimeException e) {
            System.out.println("Caught: " + e);
        }
    }

    public void testPlusWithNull() throws Throwable {
        String param = "called with: ";
        Object value = invoke(param, "plus", new Object[] { null });
        assertEquals("called with null", param + null, value);
    }

    public void testCallIntMethodWithInteger() throws Throwable {
        Object value = invoke(this, "overloadedRemove", new Object[] { new Integer(5)});
        assertEquals("called with integer", "int5", value);
    }

    public void testCallListRemove() throws Throwable {
        List list = new ArrayList();
        list.add("foo");
        list.add("bar");

        Object value = invoke(list, "remove", new Object[] { new Integer(0)});

        assertEquals("Should have just 1 item left: " + list, 1, list.size());
    }

    public void testCoerceGStringToString() throws Throwable {
        GString param = new GString(new Object[] { "James" }) {
            public String[] getStrings() {
                return new String[] { "Hello " };
            }
        };
        Object value = invoke(this, "methodTakesString", new Object[] { param });
        assertEquals("converted GString to string", param.toString(), value);
    }

    public void testCoerceGStringToStringOnGetBytes() throws Throwable {
        GString param = new GString(new Object[] { "US-ASCII" }) {
            public String[] getStrings() {
                return new String[] { "" };
            }
        };
        Object value = invoke("test", "getBytes", new Object[] { param });
        assertEquals("converted GString to string", "test".getBytes("US-ASCII").getClass(), value.getClass());
    }

    public void testBadBDToDoubleCoerce() throws Throwable {
        try {
            Object value = invoke(Math.class, "floor", new BigDecimal("1.7E309"));
        } catch (GroovyRuntimeException e) {
            assertTrue("Math.floor(1.7E309) should fail because it is out of range for a Double. "
                    +e,e.getMessage().indexOf("out of range") > 0);
            return;
        }
        fail("Math.floor(1.7E309) should fail because it is out of range for a Double.");        
    }

    public void testClassMethod() throws Throwable {
        Class c = String.class;
        Object value = invoke(c, "getName", null);
        assertEquals("Class.getName()", c.getName(), value);
        c = getClass();
        value = invoke(c, "getName", null);
        assertEquals("Class.getName()", c.getName(), value);
    }

    public void testProtectedMethod() throws Throwable {
        String param = "hello";
        Object value = invoke(this, "aProtectedMethod", param);
        assertEquals("protected method call", aProtectedMethod(param), value);
    }

    public void testPrivateMethod() throws Throwable {
        String param = "hello";
        Object value = invoke(this, "aPrivateMethod", param);
        assertEquals("private method call", aPrivateMethod(param), value);
    }

    public void testStringSubstringMethod() throws Throwable {
        String object = "hello";
        Object value = invoke(object, "substring", new Integer(2));
        assertEquals("substring(2)", object.substring(2), value);

        value = invoke(object, "substring", new Object[] { new Integer(1), new Integer(3)});
        assertEquals("substring(1,3)", object.substring(1, 3), value);
    }

    public void testListGetWithRange() throws Throwable {
        List list = Arrays.asList(new Object[] { "a", "b", "c" });
        Object range = new IntRange(0, 2);
        Object value = invoke(list, "getAt", range);
        assertTrue("Returned List: " + value, value instanceof List);
        List retList = (List) value;
        assertEquals("List size", 3, retList.size());
    }

    public void testSetLenientOnDateFormat() throws Throwable {
        SimpleDateFormat a = new SimpleDateFormat( "MM/dd/yyyy" );
        
        Object value = invoke(a, "setLenient", new Object[] { Boolean.FALSE });
        assertEquals("void method", null, value);
    }

    public void testInvokeUnknownMethod() throws Throwable {
        try {
            Object value = invoke(this, "unknownMethod", "abc");
            fail("Should have thrown an exception");
        }
        catch (GroovyRuntimeException e) {
            // worked
        }
    }

    public void testInvokeMethodWithWrongNumberOfParameters() throws Throwable {
        try {
            Object[] args = { "a", "b" };
            Object value = invoke(this, "unknownMethod", args);
            fail("Should have thrown an exception");
        }
        catch (GroovyRuntimeException e) {
            // worked
        }
    }

    public void testInvokeMethodOnNullObject() throws Throwable {
        try {
            invoke(null, "mockCallWithNoParams", null);
            fail("Should have thrown an exception");
        }
        catch (NullPointerException e) {
            // worked
        }
    }

    // Mock methods used for testing
    //-------------------------------------------------------------------------

    public Object mockCallWithNoParams() {
        return "NoParams";
    }

    public Object mockCallWithOneParam(Object value) {
        assertEquals("Method not passed in the correct value", "abc", value);
        return "OneParam";
    }

    public Object mockCallWithOneNullParam(Object value) {
        assertEquals("Method not passed in the correct value", null, value);
        return "OneParamWithNull";
    }

    public Integer mockCallWithOneCollectionParam(Object collection) {
        Collection coll = InvokerHelper.asCollection(collection);
        return new Integer(coll.size());
    }

    public Object mockOverloadedMethod() {
        return "void";
    }

    public Object mockOverloadedMethod(Object object) {
        return "Object";
    }

    public Object mockOverloadedMethod(Number object) {
        return "Number";
    }

    public Object mockOverloadedMethod(String object) {
        return "String";
    }

    public Object mockOverloadedMethod(Object object, Object bar) {
        return "Object,Object";
    }

    public Object mockOverloadedMethod(Object object, Object[] array) {
        return "Object,Object[]";
    }

    public Object badOverload(String a, Object b) {
        return "String, Object";
    }

    public Object badOverload(Object a, String b) {
        return "Object, String";
    }

    public Object methodTakesString(String x) {
        return x;
    }

    public Object overloadedRemove(int idx) {
        return "int" + idx;
    }

    public Object overloadedRemove(Object value) {
        return "Object" + value;
    }

    // Implementation methods
    //-------------------------------------------------------------------------

    protected Object aProtectedMethod(String param) {
        return param + " there!";
    }

    private Object aPrivateMethod(String param) {
        return param + " James!";
    }

    protected void assertMethodCall(Object object, String method, Object param, Object expected) {
        Object value = InvokerHelper.invokeMethod(object, method, new Object[] { param });
        assertEquals("result of method: " + method, expected, value);
    }

    /**
	 * Asserts that invoking the method chooser finds the right overloaded
	 * method implementation
	 * 
	 * @param expected
	 *            is the expected value of the method
	 * @param arguments
	 *            the argument(s) to the method invocation
	 */
    protected void assertMethodChooser(Object expected, Object arguments) throws Throwable {
        Object value = invoke(this, "mockOverloadedMethod", arguments);

        assertEquals("Invoking overloaded method for arguments: " + InvokerHelper.toString(arguments), expected, value);
    }

    protected Object invoke(Object object, String method, Object args) throws Throwable {
        try {
            return invoker.invokeMethod(object, method, args);
        }
        catch (InvokerInvocationException e) {
            throw e.getCause();
        }
    }
}
