/*
 *  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 org.codehaus.groovy.antlr.AntlrParserPluginFactory

/**
 * Units tests aimed at testing the behavior of {@link DelegatesTo} in combination
 * with static type checking.
 */
class DelegatesToSTCTest extends StaticTypeCheckingTestCase {

    void testShouldChooseMethodFromOwner() {
        assertScript '''
            class Delegate {
                int foo() { 2 }
            }
            class Owner {
                int foo() { 1 }
                int doIt(@DelegatesTo(Delegate) Closure cl) {
                    cl.delegate = new Delegate()
                    cl() as int
                }
                int test() {
                    doIt {
                        @ASTTest(phase=INSTRUCTION_SELECTION, value={
                            node = node.rightExpression
                            def target = node.getNodeMetaData(DIRECT_METHOD_CALL_TARGET)
                            assert target != null
                            assert target.declaringClass.name == 'Owner'
                        })
                        def x = foo() // as the delegation strategy is owner first, should return 1
                        x
                    }
                }
            }
            def o = new Owner()
            assert o.test() == 1
        '''
    }

    void testShouldChooseMethodFromDelegate() {
        assertScript '''
            class Delegate {
                int foo() { 2 }
            }
            class Owner {
                int foo() { 1 }
                int doIt(@DelegatesTo(strategy=Closure.DELEGATE_FIRST, value=Delegate) Closure cl) {
                    cl.delegate = new Delegate()
                    cl.resolveStrategy = Closure.DELEGATE_FIRST
                    cl() as int
                }
                int test() {
                    doIt {
                        @ASTTest(phase=INSTRUCTION_SELECTION, value={
                            node = node.rightExpression
                            def target = node.getNodeMetaData(DIRECT_METHOD_CALL_TARGET)
                            assert target != null
                            assert target.declaringClass.name == 'Delegate'
                        })
                        def x = foo() // as the delegation strategy is delegate first, should return 2
                        x
                    }
                }
            }
            def o = new Owner()
            assert o.test() == 2
        '''
    }

    void testShouldAcceptMethodCall() {
        assertScript '''
            class ExecSpec {
                boolean called = false
                void foo() {
                    called = true
                }
            }

            ExecSpec spec = new ExecSpec()

            void exec(ExecSpec spec, @DelegatesTo(value=ExecSpec, strategy=Closure.DELEGATE_FIRST) Closure param) {
                param.delegate = spec
                param()
            }

            exec(spec) {
                foo() // should be recognized because param is annotated with @DelegatesTo(ExecSpec)
            }
            assert spec.isCalled()
        '''
    }

    void testCallMethodFromOwner() {
        assertScript '''
            class Xml {
                boolean called = false
                void bar() { called = true }
                void foo(@DelegatesTo(Xml)Closure cl) { cl.delegate=this;cl() }
            }
            def mylist = [1]
            def xml = new Xml()
            xml.foo {
             mylist.each { bar() }
            }
            assert xml.called
        '''
    }

    void testEmbeddedWithAndShadowing() {
        assertScript '''
            class A {
                int foo() { 1 }
            }
            class B {
                int foo() { 2 }
            }
            def a = new A()
            def b = new B()
            int result
            a.with {
                b.with {
                    result = foo()
                }
            }
            assert result == 2
        '''
    }

    void testEmbeddedWithAndShadowing2() {
        assertScript '''
            class A {
                int foo() { 1 }
            }
            class B {
                int foo() { 2 }
            }
            def a = new A()
            def b = new B()
            int result
            b.with {
                a.with {
                    result = foo()
                }
            }
            assert result == 1
        '''
    }

    void testEmbeddedWithAndShadowing3() {
        assertScript '''
            class A {
                int foo() { 1 }
            }
            class B {
                int foo() { 2 }
            }
            class C {
                int foo() { 3 }
                void test() {
                    def a = new A()
                    def b = new B()
                    int result
                    b.with {
                        a.with {
                            result = foo()
                        }
                    }
                    assert result == 1
                }
            }
            new C().test()
        '''
    }

    void testEmbeddedWithAndShadowing4() {
        assertScript '''
            class A {
                int foo() { 1 }
            }
            class B {
                int foo() { 2 }
            }
            class C {
                int foo() { 3 }
                void test() {
                    def a = new A()
                    def b = new B()
                    int result
                    b.with {
                        a.with {
                            result = this.foo()
                        }
                    }
                    assert result == 3
                }
            }
            new C().test()
        '''
    }

    void testShouldDelegateToParameter() {
        assertScript '''
        class Foo {
            boolean called = false
            def foo() { called = true }
        }

        def with(@DelegatesTo.Target Object target, @DelegatesTo Closure arg) {
            arg.delegate = target
            arg()
        }

        def test() {
            def obj = new Foo()
            with(obj) { foo() }
            assert obj.called
        }
        test()
        '''
    }

    void testShouldDelegateToParameterUsingExplicitId() {
        assertScript '''
        class Foo {
            boolean called = false
            def foo() { called = true }
        }

        def with(@DelegatesTo.Target('target') Object target, @DelegatesTo(target='target') Closure arg) {
            arg.delegate = target
            arg()
        }

        def test() {
            def obj = new Foo()
            with(obj) { foo() }
            assert obj.called
        }
        test()
        '''
    }

    void testShouldFailDelegateToParameterUsingWrongId() {
        shouldFailWithMessages '''
        class Foo {
            boolean called = false
            def foo() { called = true }
        }

        def with(@DelegatesTo.Target('target') Object target, @DelegatesTo(target='wrongTarget') Closure arg) {
            arg.delegate = target
            arg()
        }

        def test() {
            def obj = new Foo()
            with(obj) { foo() }
            assert obj.called
        }
        test()
        ''', 'Not enough arguments found for a @DelegatesTo method call', 'Cannot find matching method'
    }

    void testShouldFailDelegateToParameterIfNoTargetSpecified() {
        shouldFailWithMessages '''
        class Foo {
            boolean called = false
            def foo() { called = true }
        }

        def with(Object target, @DelegatesTo Closure arg) {
            arg.delegate = target
            arg()
        }

        def test() {
            def obj = new Foo()
            with(obj) { foo() }
            assert obj.called
        }
        test()
        ''', 'Not enough arguments found for a @DelegatesTo method call', 'Cannot find matching method'
    }

    void testDelegatesToWithSetter() {
        assertScript '''
            class Item {
                int x
            }

            class Builder {
                private Item item = new Item()
                void setConstraints(@DelegatesTo(Item) Closure cl) {
                    def copy = cl.rehydrate(item, this, this)
                    copy()
                }
                int value() { item.x }
            }

            def b = new Builder()
            b.setConstraints {
                x = 5
            }
            assert b.value() == 5
        '''
    }

    void testDelegatesToWithSetterUsedAsProperty() {
        assertScript '''
            class Item {
                int x
            }

            class Builder {
                private Item item = new Item()
                void setConstraints(@DelegatesTo(Item) Closure cl) {
                    def copy = cl.rehydrate(item, this, this)
                    copy()
                }
                int value() { item.x }
            }

            def b = new Builder()
            b.constraints = {
                x = 5
            }
            assert b.value() == 5
        '''
    }

    void testDelegatesToWithSetterUsedAsPropertyAndErrorInPropertyName() {
        shouldFailWithMessages '''
            class Item {
                int x
            }

            class Builder {
                private Item item = new Item()
                void setConstraints(@DelegatesTo(Item) Closure cl) {
                    def copy = cl.rehydrate(item, this, this)
                    copy()
                }
                int value() { item.x }
            }

            def b = new Builder()
            b.constraints = {
                y = 5
            }
            assert b.value() == 5
        ''', '[Static type checking] - The variable [y] is undeclared.'
    }

    void testDelegatesToWithSetterUsedAsPropertyAndWith() {
        assertScript '''
            class Item {
                int x
            }

            class Builder {
                private Item item = new Item()
                void setConstraints(@DelegatesTo(Item) Closure cl) {
                    def copy = cl.rehydrate(item, this, this)
                    copy()
                }
                int value() { item.x }
            }

            def b = new Builder()
            b.with {
                constraints = {
                    x = 5
                }
            }
            assert b.value() == 5
        '''
    }

    // GROOVY-6055
    void testDelegatesToInStaticContext() {
        assertScript '''
            class Person {
                String name
                public static List<Person> findBy(@DelegatesTo(Person) Closure criteria) { [] }
            }
            List<Person> persons = Person.findBy { getName() == 'Cedric' }
            persons = Person.findBy { name == 'Cedric' }
        '''
    }

    void testDelegatesToInStaticContext2() {
        assertScript '''
            class QueryBuilder {
                List<?> where(Map params) {[]}
            }
            class Person {
                String name
                public static List<Person> findBy(@DelegatesTo(QueryBuilder) Closure criteria) { [] }
            }
            List<Person> persons = Person.findBy { where name:'Cédric' }
        '''
    }

    // GROOVY-6021
    void testShouldEnsureLastIsRecognizedAndCompiledProperly() {
        assertScript '''
            def with(@DelegatesTo.Target Object target, @DelegatesTo(strategy = Closure.DELEGATE_FIRST) Closure arg) {
                arg.delegate = target
                arg.setResolveStrategy(Closure.DELEGATE_FIRST)
                arg()
            }

            def test() {
                def obj = [1, 2]
                with(obj) {
                    print(last()) //error is here
                }
            }

            test()
        '''
    }

    // GROOVY-6091
    void testExplicitUseOfDelegateProperty() {
        assertScript '''
            def with(@DelegatesTo.Target Object target, @DelegatesTo(strategy = Closure.DELEGATE_FIRST) Closure arg) {
                arg.delegate = target
                arg.setResolveStrategy(Closure.DELEGATE_FIRST)
                arg()
            }

            def test() {
                def obj = [1, 2]
                with(obj) {
                    print(delegate.last()) //error is here
                }
            }

            test()

        '''
    }

    // GROOVY-6091
    void testExplicitUseOfDelegateMethod() {
        assertScript '''
            def with(@DelegatesTo.Target Object target, @DelegatesTo(strategy = Closure.DELEGATE_FIRST) Closure arg) {
                arg.delegate = target
                arg.setResolveStrategy(Closure.DELEGATE_FIRST)
                arg()
            }

            def test() {
                def obj = [1, 2]
                with(obj) {
                    print(getDelegate().last()) //error is here
                }
            }

            test()

        '''
    }

    void testDelegatesToGenericTypeArgument() {
        assertScript '''
            public <T> Object map(@DelegatesTo.Target List<T> target, @DelegatesTo(genericTypeIndex=0) Closure arg) {
                arg.delegate = target.join('')
                arg()
            }
            def test() {
                def result
                map(['f','o','o']) {
                    result = toUpperCase()
                }

                result
            }
            assert 'FOO'==test()
        '''
    }

    void testDelegatesToGenericTypeArgumentAndActualArgumentNotUsingGenerics() {
        assertScript '''import groovy.transform.InheritConstructors
            @InheritConstructors
            class MyList extends LinkedList<String> {}

            public <T> Object map(@DelegatesTo.Target List<T> target, @DelegatesTo(genericTypeIndex=0) Closure arg) {
                arg.delegate = target.join('')
                arg()
            }
            def test() {
                def result
                def mylist = new MyList(['f','o','o'])
                map(mylist) {
                    result = toUpperCase()
                }

                result
            }
            assert 'FOO'==test()
        '''
    }

    void testDelegatesToGenericTypeArgumentWithMissingGenerics() {
        shouldFailWithMessages '''
            public Object map(@DelegatesTo.Target List target, @DelegatesTo(genericTypeIndex=0) Closure arg) {
                arg.delegate = target.join('')
                arg()
            }
            def test() {
                def result
                map(['f','o','o']) {
                    result = toUpperCase()
                }

                result
            }
            assert 'FOO'==test()
        ''', 'Cannot use @DelegatesTo(genericTypeIndex=0) with a type that doesn\'t use generics', 'Cannot find matching method'
    }

    void testDelegatesToGenericTypeArgumentOutOfBounds() {
        shouldFailWithMessages '''
            public <T> Object map(@DelegatesTo.Target List<T> target, @DelegatesTo(genericTypeIndex=1) Closure arg) {
                arg.delegate = target.join('')
                arg()
            }
            def test() {
                def result
                map(['f','o','o']) {
                    result = toUpperCase()
                }

                result
            }
            assert 'FOO'==test()
        ''', 'Index of generic type @DelegatesTo(genericTypeIndex=1) greater than those of the selected type', 'Cannot find matching method'
    }

    void testDelegatesToGenericTypeArgumentWithNegativeIndex() {
        shouldFailWithMessages '''
            public <T> Object map(@DelegatesTo.Target List<T> target, @DelegatesTo(genericTypeIndex=-1) Closure arg) {
                arg.delegate = target.join('')
                arg()
            }
            def test() {
                def result
                map(['f','o','o']) {
                    result = toUpperCase()
                }

                result
            }
            assert 'FOO'==test()
        ''', 'Index of generic type @DelegatesTo(genericTypeIndex=-1) lower than those of the selected type', 'Cannot find matching method'
    }

    void testDelegatesToGenericTypeArgumentUsingMap() {
        assertScript '''
            public <K,V> void transform(@DelegatesTo.Target Map<K, V> map, @DelegatesTo(genericTypeIndex = 1) Closure<?> closure) {
                map.keySet().each {
                    closure.delegate = map[it]
                    map[it] = closure()
                }
            }
            def map = [1: 'a', 2: 'b', 3: 'c']
            transform(map) {
                toUpperCase()
            }
            assert map == [1: 'A', 2: 'B', 3: 'C']
        '''
    }

    void testDelegatesToGenericTypeArgumentUsingMapAndWrongIndex() {
        shouldFailWithMessages '''
            public <K,V> void transform(@DelegatesTo.Target Map<K, V> map, @DelegatesTo(genericTypeIndex = 0) Closure<?> closure) {
                map.keySet().each {
                    closure.delegate = map[it]
                    map[it] = closure()
                }
            }
            def map = [1: 'a', 2: 'b', 3: 'c']
            transform(map) {
                toUpperCase()
            }
            assert map == [1: 'A', 2: 'B', 3: 'C']
        ''', 'Cannot find matching method'
    }

    // GROOVY-6165
    void testDelegatesToGenericArgumentTypeAndTypo() {

        String code = '''import groovy.transform.*

        @TupleConstructor
        class Person { String name }

        public <T> List<T> names(
            @DelegatesTo.Target List<T> list,
            @DelegatesTo(genericTypeIndex = 0) Closure modify) {
                list.collect {
                    modify.delegate = it
                    modify()
                }
        }

        def test(List<Person> persons) {
            def names = names(persons) {
                getname().toUpperCase()
            }
            assert names == ['GUILLAUME', 'CEDRIC']
        }

        test([new Person('Guillaume'), new Person('Cedric')])
        '''

        String msg = 'Cannot find matching method'

        if (config.pluginFactory instanceof AntlrParserPluginFactory) {
            shouldFailWithMessages code, msg
        } else {
            /*
             * Because the Parrot parser provides more accurate node position information,
             * org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.addError will not be interfered by wrong node position.
             *
             * 1) TestScripttestDelegatesToGenericArgumentTypeAndTypo0.groovy: 17: [Static type checking] - Cannot find matching method TestScripttestDelegatesToGenericArgumentTypeAndTypo0#getname(). Please check if the declared type is correct and if the method exists.
             * 2) TestScripttestDelegatesToGenericArgumentTypeAndTypo0.groovy: 17: [Static type checking] - Cannot find matching method java.lang.Object#toUpperCase(). Please check if the declared type is correct and if the method exists.
             *
             */
            shouldFailWithMessages code, msg, msg
        }
    }

    // GROOVY-6323, GROOVY-6325, GROOVY-6332
    void testStaticContextAndProperty() {
        assertScript '''
            class MyCar {
                String brand
                String model
            }

            class MyCarMain {
                MyCar configureCar(@DelegatesTo(MyCar) Closure closure) {
                    def car = new MyCar()
                    closure.delegate = car
                    closure.resolveStrategy = Closure.DELEGATE_FIRST
                    closure()
                    car
                }
                static void main(String[] args) {
                    def main = new MyCarMain()
                    def car = main.configureCar {
                        brand = "BMW"
                        model = brand + " X5"
                    }
                    assert car.model == "BMW X5"
                }
            }
            MyCarMain.main()
        '''

        assertScript '''
            class MyCar {
                private String _brand
                private String _model

                String getBrand() {
                    return _brand
                }

                void setBrand(String brand) {
                    _brand = brand
                }

                String getModel() {
                    return _model
                }

                void setModel(String model) {
                    _model = model
                }
            }

            class MyCarMain {
                MyCar configureCar(@DelegatesTo(value = MyCar, strategy = Closure.DELEGATE_FIRST) Closure closure) {
                    def car = new MyCar()
                    closure.delegate = car
                    closure.resolveStrategy = Closure.DELEGATE_FIRST
                    closure()
                    car
                }

                static void main(String[] args) {
                    def main = new MyCarMain()
                    def car = main.configureCar {
                        brand = "BMW"
                        model = brand
                    }
                    assert car.model == "BMW"
                }
            }
            MyCarMain.main()
        '''

        assertScript '''
            class Car {
              private String _brand
              String getBrand() { _brand }
              void setBrand(String brand) { _brand = brand }
            }

            class Builder {
              def <T> T configure(@DelegatesTo.Target Class<T> target, @DelegatesTo(genericTypeIndex=0) Closure cl) {
                def obj = target.newInstance()
                cl.delegate = obj
                cl.resolveStrategy = Closure.DELEGATE_FIRST
                cl.call()
                obj
              }
            }

            class Main {
              void run() {
                def builder = new Builder()
                def car = builder.configure(Car) {
                  brand = brand
                }
              }
            }

            new Main().run()
        '''
    }

    // GROOVY-5998
    void testSubscriptOperatorOnPropertiesWithBuilder() {
        assertScript '''
            import static groovy.lang.Closure.*

            class DatasourceBuilder {
                Map<String,String> attrs = [:]
            }

            void datasource(@DelegatesTo(strategy = DELEGATE_FIRST, value = DatasourceBuilder) Closure c) {}

            void foo() {
               datasource {
                   attrs['some'] = 'foo'
               }
            }

            foo()
        '''
    }

    void testDelegatesToNestedGenericType() {
        assertScript '''
            trait Configurable<ConfigObject> {
                ConfigObject configObject

                void configure(Closure<Void> configSpec) {
                    configSpec.resolveStrategy = Closure.DELEGATE_FIRST
                    configSpec.delegate = configObject
                    configSpec()
                }
            }
            public <T,U extends Configurable<T>> U configure(Class<U> clazz, @DelegatesTo(type="T") Closure configSpec) {
                Configurable<T> obj = (Configurable<T>) clazz.newInstance()
                obj.configure(configSpec)
                obj
            }
            class Module implements Configurable<ModuleConfig> {
                String value

                 Module(){
                    configObject = new ModuleConfig()
                 }

                 @Override
                 void configure(Closure<Void> configSpec) {
                    Configurable.super.configure(configSpec)
                    value = "${configObject.name}-${configObject.version}"
                 }
            }
            class ModuleConfig {
                String name
                String version
            }
            def module = configure(Module) {
                name = 'test'
                version = '1.0'
            }
            assert module.value == 'test-1.0'
        '''
    }

    void testDelegatesToWithType2() {
        assertScript '''
            public <T> boolean evalAsSet(List<T> list, @DelegatesTo(type="Set<T>") Closure<Boolean> cl) {
                cl.delegate = list as Set
                cl()
            }
            assert evalAsSet([1,1,2,3]) {
                size() == 3
            }
        '''
    }
}
