/*
 *  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 groovy.transform.stc

import groovy.transform.CompileStatic

/**
 * Unit tests for static type checking : loops.
 */
class LoopsSTCTest extends StaticTypeCheckingTestCase {

    void testMethodCallInLoop() {
        assertScript '''
            int foo(int x) { x+1 }
            int x = 0
            for (int i=0;i<10;i++) {
                x = foo(x)
            }
        '''
    }

    void testMethodCallInLoopAndDef() {
        assertScript '''
            int foo(int x) { x+1 }
            def x = 0
            for (int i=0;i<10;i++) {
                x = foo(x)
            }
        '''
    }

    // GROOVY-8882
    void testStringCollectionLoop() {
        for (char c in 'abc') assert c instanceof Character
        for (Character c in 'abc') assert c instanceof Character
        for (String s in 'abc') assert s instanceof String
        for (s in 'abc') assert s instanceof String
    }

    // GROOVY-8882
    @CompileStatic
    void testStringCollectionLoopCS() {
        for (char c in 'abc') assert c instanceof Character
        for (Character c in 'abc') assert c instanceof Character
        for (String s in 'abc') assert s instanceof String
        for (s in 'abc') assert s instanceof String
    }

    void testMethodCallWithEachAndDefAndTwoFooMethods() {
        shouldFailWithMessages '''
            Date foo(Integer x) { new Date() }
            Integer foo(Date x) { 1 }
            def x = 0
            10.times {
                 // there are two possible target methods. This is not a problem for STC, but it is for static compilation
                x = foo(x)
            }
        ''', 'Cannot find matching method'
    }

    void testMethodCallInLoopAndDefAndTwoFooMethods() {
        shouldFailWithMessages '''
            Date foo(Integer x) { new Date() }
            Integer foo(Date x) { 1 }
            def x = 0
            for (int i=0;i<10;i++) {
                 // there are two possible target methods. This is not a problem for STC, but it is for static compilation
                x = foo(x)
            }
        ''', 'Cannot find matching method'
    }

    void testMethodCallInLoopAndDefAndTwoFooMethodsAndOneWithBadType() {
        shouldFailWithMessages '''
            Double foo(Integer x) { x+1 }
            Date foo(Double x) { new Date((long)x) }
            def x = 0
            for (int i=0;i<10;i++) {
                // there are two possible target methods and one returns a type which is assigned to 'x'
                // then called in turn as a parameter of foo(). There's no #foo(Date)
                x = foo(x)
            }
        ''', 'Cannot find matching method'
    }

    void testMethodCallInLoopAndDefAndTwoFooMethodsAndOneWithBadTypeAndIndirection() {
        shouldFailWithMessages '''
            Double foo(Integer x) { x+1 }
            Date foo(Double x) { new Date((long)x) }
            def x = 0
            for (int i=0;i<10;i++) {
                def y = foo(x)
                // there are two possible target methods and one returns a type which is assigned to 'x'
                // then called in turn as a parameter of foo(). There's no #foo(Date)
                x = y
            }
        ''', 'Cannot find matching method'
    }

    void testMethodCallWithEachAndDefAndTwoFooMethodsAndOneWithBadTypeAndIndirection() {
        shouldFailWithMessages '''
            Double foo(Integer x) { x+1 }
            Date foo(Double x) { new Date((long)x) }
            def x = 0
            10.times {
                def y = foo(x)
                // there are two possible target methods and one returns a type which is assigned to 'x'
                // then called in turn as a parameter of foo(). There's no #foo(Date)
                x = y
            }
        ''', 'Cannot find matching method'
    }

    // GROOVY-5587
    void testMapEntryInForInLoop() {
        assertScript '''
            @ASTTest(phase=INSTRUCTION_SELECTION, value= {
                lookup('forLoop').each {
                    assert it instanceof org.codehaus.groovy.ast.stmt.ForStatement
                    def collection = it.collectionExpression // MethodCallExpression
                    def inft = collection.getNodeMetaData(INFERRED_TYPE)
                    assert inft == make(Set)
                    def entryInft = inft.genericsTypes[0].type
                    assert entryInft == make(Map.Entry)
                    assert entryInft.genericsTypes[0].type == STRING_TYPE
                    assert entryInft.genericsTypes[1].type == Integer_TYPE
                }
            })
            void test() {
                def result = ""
                def sum = 0
                forLoop:
                for ( Map.Entry<String, Integer> it in [a:1, b:3].entrySet() ) {
                   result += it.getKey()
                   sum += it.getValue()
                }
                assert result == "ab"
                assert sum == 4
            }
            test()
        '''
    }

    void testShouldNotInferSoftReferenceAsComponentType() {
        assertScript '''import java.lang.reflect.Field
            import org.codehaus.groovy.ast.stmt.ForStatement

            @ASTTest(phase=INSTRUCTION_SELECTION, value= {
                def FIELD_ARRAY = make(Field).makeArray()
                def forStmt = lookup('myLoop')[0]
                assert forStmt instanceof ForStatement
                def collectionType = forStmt.collectionExpression.getNodeMetaData(INFERRED_TYPE)
                assert collectionType == FIELD_ARRAY
            })
            void forInTest() {
                int i = 0;
                myLoop:
                for (def field : String.class.declaredFields) {
                    i++;
                }
                assert i > 0
            }
        '''
    }

    // GROOVY-5640
    void testShouldInferComponentTypeAsIterableOfNodes() {
        assertScript '''import org.codehaus.groovy.ast.stmt.ForStatement
        class Node {}

        interface Traverser {
            Iterable<Node> nodes()
        }

        class MyTraverser implements Traverser {

            Iterable<Node> nodes() {
                []
            }
        }

        @ASTTest(phase=INSTRUCTION_SELECTION, value= {
            def forStmt = lookup('loop')[0]
            assert forStmt instanceof ForStatement
            def collectionType = forStmt.collectionExpression.getNodeMetaData(INFERRED_TYPE)
            assert collectionType == make(Iterable)
            assert collectionType.isUsingGenerics()
            assert collectionType.genericsTypes.length == 1
            assert collectionType.genericsTypes[0].type.name == 'Node'
        })
        void test() {
            loop:
            for (def node : new MyTraverser().nodes()) {
                println node.class.name
            }
        }

        '''
    }

    // GROOVY-5641
    void testShouldInferLoopElementTypeWithUndeclaredType() {
        assertScript '''import org.codehaus.groovy.ast.stmt.ForStatement
        @ASTTest(phase=INSTRUCTION_SELECTION, value= {
            def forStmt = lookup('loop')[0]
            assert forStmt instanceof ForStatement
            def collectionType = forStmt.collectionExpression.getNodeMetaData(INFERRED_TYPE)
            assert collectionType == make(IntRange)
        })
        void foo() {
            int[] perm = new int[10]
            loop:
            for (i in 0..<10) {
              assert perm[i-0] == 0
            }
        }
        '''
    }
}

