/*
 *  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.
 */

import org.junit.jupiter.api.Test

import static groovy.test.GroovyAssert.assertScript

final class ScriptsAndClassesSpecTest {

    @Test
    void testMainMethod() {
        assertScript '''
            // tag::groovy_class_with_main_method[]
            class Main {                                    // <1>
                static void main(String... args) {          // <2>
                    println 'Groovy world!'                 // <3>
                }
            }
            // end::groovy_class_with_main_method[]
        '''
        assertScript '''
            // tag::groovy_script[]
            println 'Groovy world!'
            // end::groovy_script[]
        '''

        assertScript '''
            // tag::groovy_script_equiv[]
            import org.codehaus.groovy.runtime.InvokerHelper
            class Main extends Script {                     // <1>
                def run() {                                 // <2>
                    println 'Groovy world!'                 // <3>
                }
                static void main(String[] args) {           // <4>
                    InvokerHelper.runScript(Main, args)     // <5>
                }
            }
            // end::groovy_script_equiv[]
        '''

        assertScript '''
            import groovy.transform.CompileStatic
            // tag::script_with_explicit_static_main[]
            @CompileStatic
            static main(args) {
                println 'Groovy world!'
            }
            // end::script_with_explicit_static_main[]
        '''

        assertScript '''
            import groovy.transform.*
            import com.fasterxml.jackson.annotation.*
            import com.fasterxml.jackson.databind.ObjectMapper

            // tag::script_with_explicit_instance_run[]
            @JsonIgnoreProperties(["binding"])
            def run() {
                var mapper = new ObjectMapper()
                assert mapper.writeValueAsString(this) == '{"pets":["cat","dog"]}'
            }

            public pets = ['cat', 'dog']
            // end::script_with_explicit_instance_run[]
        '''
    }

    @Test
    void testJep445Definition() {
        def runScript = { scriptText -> new GroovyShell().run(scriptText, 'ScriptSnippet', new String[0]) }

        runScript '''
            // tag::jep445_barescript[]
            void main(args) {
                println new Date()
            }
            // end::jep445_barescript[]
        '''

        runScript '''
            // tag::jep445_script[]
            def main() {
                assert upper(foo) + lower(bar) == 'FOObar'
            }

            def upper(s) { s.toUpperCase() }

            def lower = String::toLowerCase
            def (foo, bar) = ['Foo', 'Bar']      // <1>
            // end::jep445_script[]
        '''
    }

    @Test
    void testMethodDefinition() {
        assertScript '''
            // tag::method_in_script[]
            int fib(int n) {
                n < 2 ? 1 : fib(n-1) + fib(n-2)
            }
            assert fib(10)==89
            // end::method_in_script[]
        '''

        assertScript '''
            // tag::multiple_methods_assembly[]
            println 'Hello'                                 // <1>

            int power(int n) { 2**n }                       // <2>

            println "2^6==${power(6)}"                      // <3>
            // end::multiple_methods_assembly[]
        '''

        assertScript '''
            // tag::multiple_methods_assembly_equiv[]
            import org.codehaus.groovy.runtime.InvokerHelper
            class Main extends Script {
                int power(int n) { 2** n}                   // <1>
                def run() {
                    println 'Hello'                         // <2>
                    println "2^6==${power(6)}"              // <3>
                }
                static void main(String[] args) {
                    InvokerHelper.runScript(Main, args)
                }
            }
            // end::multiple_methods_assembly_equiv[]
        '''
    }

    @Test
    void testScriptVariables() {
        assertScript '''
            // tag::script_with_variables[]
            int x = 1
            int y = 2
            assert x+y == 3
            // end::script_with_variables[]
        '''
        assertScript '''
            // tag::script_with_untyped_variables[]
            x = 1
            y = 2
            assert x+y == 3
            // end::script_with_untyped_variables[]
        '''
    }
}
