/*
 *  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.
 */
package org.codehaus.groovy.classgen.asm.sc

import org.codehaus.groovy.classgen.asm.AbstractBytecodeTestCase
import org.codehaus.groovy.runtime.MethodClosure

import static org.codehaus.groovy.control.CompilerConfiguration.DEFAULT as config

class StaticCompilationTest extends AbstractBytecodeTestCase {
    void testEmptyMethod() {
        def bytecode = compile([method:'m'],'''
            @groovy.transform.CompileStatic
            void m() {}
        ''')
        assert bytecode.hasStrictSequence(
                ['public m()V',
                        'L0',
                        'LINENUMBER 3 L0',
                        'RETURN']
        )
    }

    void testPrimitiveReturn1() {
        def bytecode = compile([method:'m'],'''
            @groovy.transform.CompileStatic
            int m() { 1 }
        ''')
        assert bytecode.hasStrictSequence(
                ['ICONST_1', 'IRETURN']
        )
    }

    void testPrimitiveReturn2() {
        def bytecode = compile([method:'m'],'''
            @groovy.transform.CompileStatic
            long m() { 1L }
        ''')
        assert bytecode.hasStrictSequence(
                ['LCONST_1', 'LRETURN']
        )
    }

    void testPrimitiveReturn3() {
        def bytecode = compile([method:'m'],'''
            @groovy.transform.CompileStatic
            short m() { 1 }
        ''')
        assert bytecode.hasStrictSequence(
                ['ICONST_1', 'I2S', 'IRETURN']
        )
    }

    void testPrimitiveReturn4() {
        def bytecode = compile([method:'m'],'''
            @groovy.transform.CompileStatic
            byte m() { 1 }
        ''')
        assert bytecode.hasStrictSequence(
                ['ICONST_1', 'I2B', 'IRETURN']
        )
    }

    void testIdentityReturns() {
        def bytecode = compile([method:'m'],'''
            @groovy.transform.CompileStatic
            int m(int i) { i }
        ''')
        assert bytecode.hasStrictSequence(
                ['ILOAD', 'IRETURN']
        )

        bytecode = compile([method:'m'],'''
            @groovy.transform.CompileStatic
            long m(long l) { l }
        ''')
        assert bytecode.hasStrictSequence(
                ['LLOAD', 'LRETURN']
        )

        bytecode = compile([method:'m'],'''
            @groovy.transform.CompileStatic
            short m(short l) { l }
        ''')
        assert bytecode.hasStrictSequence(
                ['ILOAD', 'IRETURN']
        )

        bytecode = compile([method:'m'],'''
            @groovy.transform.CompileStatic
            float m(float l) { l }
        ''')
        assert bytecode.hasStrictSequence(
                ['FLOAD', 'FRETURN']
        )

        bytecode = compile([method:'m'],'''
            @groovy.transform.CompileStatic
            double m(double l) { l }
        ''')
        assert bytecode.hasStrictSequence(
                ['DLOAD', 'DRETURN']
        )

        bytecode = compile([method:'m'],'''
            @groovy.transform.CompileStatic
            Object m(Object l) { l }
        ''')
        assert bytecode.hasStrictSequence(
                ['ALOAD', 'ARETURN']
        )
    }

    void testSingleAssignment() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        void m() {
            int a = 1
        }''').hasSequence([
                "ICONST_1",
                "ISTORE",
                "RETURN"
        ])
    }

    void testReturnSingleAssignment() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        int m() {
            int a = 1
        }''').hasSequence([
                "ICONST_1",
                "ISTORE",
                "ILOAD",
                "IRETURN"
        ])
    }

    void testIntLeftShift() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        void m() {
            int a = 1
            int b = a << 32
        }''').hasStrictSequence([
                "ILOAD",
                "BIPUSH 32",
                "ISHL"
        ])
    }

    void testLongLeftShift() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        void m() {
            long a = 1L
            long b = a << 32
        }''').hasStrictSequence([
                "LLOAD",
                "BIPUSH 32",
                "LSHL"
        ])
    }

    void testArrayGet() {
        if (config.indyEnabled) return;
        // this test is done with indy in another tests case
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        void m(int[] arr) {
            arr[0]
        }''').hasStrictSequence([
                "ALOAD 1",
                "ICONST_0",
                "INVOKESTATIC org/codehaus/groovy/runtime/BytecodeInterface8.intArrayGet ([II)I"
        ])
    }

    void testArraySet() {
        if (config.indyEnabled) return;
        // this test is done with indy in another tests case
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        void m(int[] arr) {
            arr[0] = 0
        }''').hasStrictSequence([
                "ICONST_0",
                "ISTORE 2",
                "ALOAD 1",
                "ICONST_0",
                "ILOAD 2",
                "INVOKESTATIC org/codehaus/groovy/runtime/BytecodeInterface8.intArraySet ([III)V"
        ])
    }

/*    void testPlusPlus() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        void m() {
            int i = 0
            i++
        }''').hasStrictSequence([
                "IINC",
        ])

    }

    void testMinusMinus() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        void m() {
            int i = 0
            i--
        }''').hasStrictSequence([
                "IINC",
        ])

    }

    void testPlusEquals() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        int m() {
            int i = 0
            i += 13
            return i
        }''').hasStrictSequence([
                "ILOAD",
                "ILOAD",
                "IADD",
                "ISTORE"
        ])
    }

    void testPlusEqualsFromArgs() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        void m(int i, int j) {
            i += j
        }''').hasStrictSequence([
                "ILOAD",
                "ILOAD",
                "IADD",
                "ISTORE"
        ])
    }*/

    void testFlow() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        String m(String str) {
            def obj = 1
            obj = str
            obj.toUpperCase()
        }
        m 'Cedric'
        ''').hasStrictSequence([
                "ICONST",
                "INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;",
                "ASTORE",
                "L1",
                "ALOAD 2",
                "POP",
                "L2",
                "LINENUMBER",
                "ALOAD 1",
                "ASTORE 3",
                "ALOAD 3",
                "ASTORE 2",
                "ALOAD 3",
                "POP",
                "L3",
                "LINENUMBER",
                "ALOAD 2",
                "CHECKCAST java/lang/String",
                "INVOKEVIRTUAL java/lang/String.toUpperCase ()Ljava/lang/String;",
                "ARETURN",
                "L4"
        ])
    }

    void testInstanceOf() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        void m(Object str) {
            if (str instanceof String) {
                str.toUpperCase()
            }
        }
        m 'Cedric'
        ''').hasStrictSequence([
                "ALOAD",
                "CHECKCAST java/lang/String",
                "INVOKEVIRTUAL java/lang/String.toUpperCase ()Ljava/lang/String;"
        ])
    }

    void testShouldGenerateDirectConstructorCall() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        class Foo {
            String msg
            Foo(int x, String y) { msg = y*x }
            static Foo foo() {
                Foo result = [2,'Bar']
            }
        }
        ''').hasStrictSequence([
                'ICONST_2',
                'LDC "Bar"',
                'INVOKESPECIAL Foo.<init> (ILjava/lang/String;)V'
        ])
    }

    void testShouldGenerateDirectArrayConstruct() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        void m() {
            int[] arr = [123,456]
        }
        ''').hasStrictSequence([
                'ICONST_2',
                'NEWARRAY T_INT',
                'DUP',
                'ICONST_0',
                'BIPUSH 123',
                'IASTORE'
        ])
    }

    void testShouldGenerateDirectBooleanArrayConstruct() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        void m() {
            boolean[] arr = [123,false]
        }
        ''').hasStrictSequence([
                'ICONST_2',
                'NEWARRAY T_BOOLEAN',
                'DUP',
                'ICONST_0',
                'BIPUSH 123',
                'INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;',
                'INVOKESTATIC org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.booleanUnbox (Ljava/lang/Object;)Z',
                'BASTORE'
        ])
    }

    void testShouldTriggerDirectCallToOuterClassGetter() {
        assert compile([method: 'fromInner',classNamePattern:'.*Inner.*'], '''
class Holder {
    String value
}

@groovy.transform.CompileStatic
class Outer {
    String outerProperty = 'outer'
    private class Inner {
        String fromInner() {
            Holder holder = new Holder()
            holder.value = outerProperty
            holder.value
        }
    }

    String blah() {
        new Inner().fromInner()
    }
}

def o = new Outer()
assert o.blah() == 'outer'
''').hasStrictSequence([
        'GETFIELD Outer$Inner.this$0',
        'INVOKEVIRTUAL Outer.getOuterProperty',
        'DUP',
        'ASTORE',
        'ALOAD',
        'ALOAD',
        'INVOKEVIRTUAL Holder.setValue'
])
    }

    void testShouldOptimizeBytecodeByAvoidingCreationOfMopMethods() {
        def shell = new GroovyShell()
        def clazz = shell.evaluate '''
            import groovy.transform.TypeCheckingMode
            import groovy.transform.CompileStatic

            @CompileStatic
            class A {
                def doSomething() { 'A' }
            }

            @CompileStatic
            class B extends A {
                def doSomething() { 'B' + super.doSomething() }
            }

            B
        '''
        assert clazz instanceof Class
        assert clazz.name == 'B'
        def mopMethods = clazz.declaredMethods.findAll { it.name =~ /(super|this)\$/ }
        assert mopMethods.empty
    }

    void testShouldNotOptimizeBytecodeForMopMethodsBecauseOfSkip() {
        def shell = new GroovyShell()
        def clazz = shell.evaluate '''
            import groovy.transform.TypeCheckingMode
            import groovy.transform.CompileStatic

            @CompileStatic
            class A {
                def doSomething() { 'A' }
            }

            @CompileStatic
            class B extends A {
                @CompileStatic(TypeCheckingMode.SKIP)
                def doSomething() { 'B' + super.doSomething() }
            }

            B
        '''
        assert clazz instanceof Class
        assert clazz.name == 'B'
        def mopMethods = clazz.declaredMethods.findAll { it.name =~ /(super|this)\$/ }
        assert !mopMethods.empty
    }

    // GROOVY-7124
    void testUseInvokeVirtualPreferredOverInvokeInterface() {
        assert compile([method: 'foo',classNamePattern:'B'], '''
        interface A { void m() }
        class B implements A {
            void m() {}
            @groovy.transform.CompileStatic
            void foo() {
                m()
            }
        }

        ''').hasStrictSequence(['INVOKEVIRTUAL B.m'])
    }

    void testShouldNotTryToCastToSupposedDelegateType() {
        assertScript '''
            @groovy.transform.CompileStatic
            class ClassCastOhNoes {
               def foo(def o) {
                   def cl = {
                       delegate.getClass()
                   }
                   cl.delegate = o
                   cl()
               }
            }
            new ClassCastOhNoes().foo(100)
        '''
    }

    void testShouldOptimizeCharInit() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        void m() {
            char c = 'x'
        }
        ''').hasStrictSequence([
                'LINENUMBER 4',
                'BIPUSH 120',
                'ISTORE'
        ])
    }

    void testShouldOptimizeCharComparison() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        void m() {
            char c1 = 'x'
            char c2 = 'x'
            boolean b = c1==c2
        }
        ''').hasSequence([
                'LINENUMBER 4',
                'BIPUSH 120',
                'ISTORE',
                'BIPUSH 120',
                'ISTORE',
                'ILOAD',
                'ILOAD',
                'IF_ICMPNE',
        ])

        // make sure the code passes
        assertScript '''
            @groovy.transform.CompileStatic
            void m() {
                char c1 = 'x'
                char c2 = 'x'
                boolean b = c1==c2
                assert b
                char c3 = 'z'
                b = c1==c3
                assert !b
            }
            m()
        '''
    }

    void testForEachLoopOptimization() {
        def loop_init = [
                'ALOAD', // load array (might be more complex than just ALOAD in general case)
                'DUP',
                'ASTORE', // store array to local var
                'ARRAYLENGTH', // get array len
                'ISTORE', // store it to local var
                'ICONST_0',
                'ISTORE', // initialize loop index
                'ILOAD', // load loop index
                'ILOAD', // load array length
                'IF_ICMPGE' // if greater or equal, end of loop
        ]

        // int[]
        def intExample = '''
        @groovy.transform.CompileStatic
        void m(int[] arr) {
            for (int i: arr) {
               println(i)
            }
        }
        m([1,2] as int[])
        '''
        assert compile([method:'m'], intExample).hasSequence([*loop_init,'IALOAD','ISTORE'])

        // short[]
        def shortExample = '''
        @groovy.transform.CompileStatic
        void m(short[] arr) {
            for (short i: arr) {
               println(i)
            }
        }
        m([1,2] as short[])
        '''
        assert compile([method:'m'], shortExample).hasSequence([*loop_init,'SALOAD','ISTORE'])

        // byte[]
        def byteExample = '''
        @groovy.transform.CompileStatic
        void m(byte[] arr) {
            for (byte i: arr) {
               println(i)
            }
        }
        m([1,2] as byte[])
        '''
        assert compile([method:'m'], byteExample).hasSequence([*loop_init,'BALOAD','ISTORE'])

        // long[]
        def longExample = '''
        @groovy.transform.CompileStatic
        void m(long[] arr) {
            for (long i: arr) {
               println(i)
            }
        }
        m([1,2] as long[])
        '''
        assert compile([method:'m'], longExample).hasSequence([*loop_init,'LALOAD','LSTORE'])

       // char[]
        def charExample = '''
        @groovy.transform.CompileStatic
        void m(char[] arr) {
            for (char i: arr) {
               println(i)
            }
        }
        m('foo'.toCharArray())
        '''
        assert compile([method:'m'], charExample).hasSequence([*loop_init,'CALOAD','ISTORE'])

       // boolean[]
        def boolExample = '''
        @groovy.transform.CompileStatic
        void m(boolean[] arr) {
            for (boolean i: arr) {
               println(i)
            }
        }
        m([true,false] as boolean[])
        '''
        assert compile([method:'m'], boolExample).hasSequence([*loop_init,'BALOAD','ISTORE'])

        // float[]
        def floatExample = '''
        @groovy.transform.CompileStatic
        void m(float[] arr) {
            for (float i: arr) {
               println(i)
            }
        }
        m([1.5f,2.0f] as float[])
        '''
        assert compile([method:'m'], floatExample).hasSequence([*loop_init,'FALOAD','FSTORE'])

        // double[]
        def doubleExample = '''
        @groovy.transform.CompileStatic
        void m(double[] arr) {
            for (double i: arr) {
               println(i)
            }
        }
        m([1.1,2.2] as double[])
        '''
        assert compile([method:'m'], doubleExample).hasSequence([*loop_init,'DALOAD','DSTORE'])

        // Any[]
        def anyExample = '''
        @groovy.transform.CompileStatic
        void m(String[] arr) {
            for (String i: arr) {
               println(i)
            }
        }
        m(['a','b'] as String[])
        '''
        assert compile([method:'m'], anyExample).hasSequence([*loop_init,'AALOAD','ASTORE'])

        // now check that everything runs fine
        [byteExample,shortExample, intExample, charExample, boolExample,
         longExample, floatExample, doubleExample, anyExample].each { script ->
            assertScript(script)
        }
    }

    void testCompareWithCharOptimization() {
        String code = '''
        @groovy.transform.CompileStatic
        boolean m(char[] arr) {
            char c = arr[0]
            ' '==c
        }
        assert m(' abc '.toCharArray()) == true
        '''
        assert compile([method:'m'],code).hasSequence(['BIPUSH','ILOAD','IF_ICMPNE'])
        assertScript(code)

        code = '''
        @groovy.transform.CompileStatic
        boolean m(char[] arr) {
            char c = arr[0]
            c==' '
        }
        assert m(' abc '.toCharArray()) == true
        '''
        assert compile([method:'m'],code).hasSequence(['ILOAD','BIPUSH','IF_ICMPNE'])
        assertScript(code)
    }

    void testShouldRemoveUnnecessaryCast() {
        assert compile([method:'m'],'''
        @groovy.transform.CompileStatic
        void m() {
            char c = (char) 'x'
        }
        ''').hasStrictSequence([
                'LINENUMBER 4',
                'BIPUSH 120',
                // No checkcast, but the idea is to check that further optimization was done
                // because the RHS is no longer a CastExpression but a ConstantExpression
                'ISTORE'
        ])
    }

    void testInstanceMethodReference() {
        // dynamic case should be a method closure
        assert String::toUpperCase instanceof MethodClosure

        // static case should be compiled into functional interface
        String code = '''
        import groovy.transform.CompileStatic
        import java.util.stream.Collectors

        @CompileStatic
        void m() {
            assert ['foo'].stream().map(String::toUpperCase).collect(Collectors.toList()) == ['FOO']
        }
        m()
        '''
        assert compile([method:'m'],code).hasSequence([
                'INVOKEDYNAMIC apply()Ljava/util/function/Function;',
                /* handle kind 0x6 : INVOKESTATIC */
                'java/lang/invoke/LambdaMetafactory.metafactory',
                /* handle kind 0x5 : INVOKEVIRTUAL */
                'java/lang/String.toUpperCase()Ljava/lang/String;'
        ])
        assertScript(code)
    }
}
