/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed 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.transform

import org.codehaus.groovy.control.CompilationUnit
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.transform.GroovyASTTransformation
import org.codehaus.groovy.transform.ASTTransformation
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.ast.ModuleNode
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.control.Phases

/**
 * Tests whether local and global transforms are successfully detected, loaded,
 * and run if a custom class loader is used for resolving compile dependencies
 * that does not delegate to the compiler's defining class loader (e.g. to
 * avoid pollution of the compile classpath).
 *
 * @author Peter Niederwieser
 */
class TransformsAndCustomClassLoadersTest extends GroovyTestCase {
    void testLocalTransform() {
        def resolvingLoader = new GroovyProjectClassesLoader()
        def transformLoader = new GroovyClassLoader(TransformsAndCustomClassLoadersTest.classLoader)
        checkIsIsolated(resolvingLoader)

        def clazz = compileAndLoadClass("@Immutable class Foo { String bar }", resolvingLoader, transformLoader)
        checkIsImmutable(clazz)
    }

    void testGlobalTransform() {
        def resolvingLoader = new GroovyProjectClassesLoader()
        def transformLoader = new ToUpperCaseTransformLoader()
        checkIsIsolated(resolvingLoader)

        def clazz = compileAndLoadClass("class Foo {}", resolvingLoader, transformLoader)
        assert clazz
        assert clazz.name == "FOO"
    }

    private compileAndLoadClass(String source, GroovyClassLoader dependencyLoader, GroovyClassLoader transformLoader) {
        def unit = new CompilationUnit(null, null, dependencyLoader, transformLoader)
        unit.addSource(new SourceUnit("", source, new CompilerConfiguration(), null, null))
        unit.compile(Phases.CLASS_GENERATION)

        def classInfo = unit.classes[0]
        assert classInfo
        return transformLoader.defineClass(classInfo.name, classInfo.bytes)
    }

    private checkIsIsolated(ClassLoader loader) {
        def clazz = loader.loadClass(CompilationUnit.name)
        assert clazz
        assert clazz != CompilationUnit
    }

    private checkIsImmutable(Class clazz) {
        try {
            def foo = clazz.newInstance(["setting property"] as Object[])
            foo.bar = "updating property"
            fail()
        } catch (ReadOnlyPropertyException expected) {}
    }
}

/**
 * A class loader that can load classes in the Groovy project,
 * but does so without delegating to another class loader.
 */
class GroovyProjectClassesLoader extends GroovyClassLoader {
    private bootstrapClassLoader = new URLClassLoader([] as URL[], (ClassLoader) null)

    GroovyProjectClassesLoader() {
        super(null, null, false)
        for (url in getGroovyLoaderURLs())
            addURL(url)
        checkCanLoadGroovyClasses()
        checkCanLoadOrgCodehausGroovyClasses()
    }

    private URL[] getGroovyLoaderURLs() {
        def groovyLoader = Closure.classLoader
        if (groovyLoader instanceof URLClassLoader)
            return groovyLoader.URLs
        else
            assert false, "sorry, GroovyProjectClassesLoader doesn't work in this class loader environment"
    }

    private checkCanLoadGroovyClasses() {
        assert loadClass(GroovyShell.name)
    }

    private checkCanLoadOrgCodehausGroovyClasses() {
        assert loadClass(CompilationUnit.name)
    }

    @Override
    synchronized Class loadClass(String name, boolean resolve) {
        def clazz = doLoadClass(name)
        if (resolve) resolveClass(clazz)
        return clazz
    }

    private Class doLoadClass(String name) {
        def clazz = findLoadedClass(name)
        if (clazz != null) return clazz

        if (name.startsWith("java."))
            return bootstrapClassLoader.loadClass(name)

        return findClass(name)
    }
}

class ToUpperCaseTransformLoader extends GroovyClassLoader {
    ToUpperCaseTransformLoader() {
        super(CompilationUnit.classLoader)
    }

    Enumeration getResources(String name) {
        if (name.equals("META-INF/services/org.codehaus.groovy.transform.ASTTransformation"))
            return Collections.enumeration([getURL()])
        else
          return super.getResources(name)
    }

    def getURL() {
        return new FakeURLFactory().createURL("org.codehaus.groovy.transform.ToUpperCaseTransform")
    }
}

@GroovyASTTransformation(phase = CompilePhase.CONVERSION)
class ToUpperCaseTransform implements ASTTransformation {
    void visit(ASTNode[] nodes, SourceUnit source) {
        assert nodes[0] instanceof ModuleNode

        for (clazz in nodes[0].classes)
            clazz.name = clazz.name.toUpperCase()
    }
}

