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

import groovy.lang.GroovyRuntimeException;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotatedNode;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.CompileUnit;
import org.codehaus.groovy.ast.ConstructorNode;
import org.codehaus.groovy.ast.FieldNode;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.Parameter;
import org.codehaus.groovy.ast.PropertyNode;
import org.codehaus.groovy.classgen.asm.BytecodeHelper;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

/**
 * To generate a class that has all the fields and methods, except that fields are not initialized
 * and methods are empty. It's intended for being used as a place holder during code generation
 * of reference to the "this" class itself.
 */
public class DummyClassGenerator extends ClassGenerator {

    private final ClassVisitor cv;
    private MethodVisitor mv;
    private final GeneratorContext context;

    // current class details
    private ClassNode classNode;
    private String internalClassName;
    private String internalBaseClassName;


    public DummyClassGenerator(
            GeneratorContext context,
            ClassVisitor classVisitor,
            ClassLoader classLoader,
            String sourceFile) {
        this.context = context;
        this.cv = classVisitor;
    }

    // GroovyClassVisitor interface
    //-------------------------------------------------------------------------
    public void visitClass(ClassNode classNode) {
        try {
            this.classNode = classNode;
            this.internalClassName = BytecodeHelper.getClassInternalName(classNode);

            //System.out.println("Generating class: " + classNode.getName());

            this.internalBaseClassName = BytecodeHelper.getClassInternalName(classNode.getSuperClass());

            cv.visit(
                    Opcodes.V1_3,
                    classNode.getModifiers(),
                    internalClassName,
                    null,
                    internalBaseClassName,
                    BytecodeHelper.getClassInternalNames(classNode.getInterfaces())
            );

            classNode.visitContents(this);

            for (ClassNode innerClass : innerClasses) {
                ClassNode innerClassType = innerClass;
                String innerClassInternalName = BytecodeHelper.getClassInternalName(innerClassType);
                String outerClassName = internalClassName; // default for inner classes
                MethodNode enclosingMethod = innerClass.getEnclosingMethod();
                if (enclosingMethod != null) {
                    // local inner classes do not specify the outer class name
                    outerClassName = null;
                }
                cv.visitInnerClass(
                        innerClassInternalName,
                        outerClassName,
                        innerClassType.getName(),
                        innerClass.getModifiers());
            }
            cv.visitEnd();
        }
        catch (GroovyRuntimeException e) {
            e.setModule(classNode.getModule());
            throw e;
        }
    }

    public void visitConstructor(ConstructorNode node) {

        visitParameters(node, node.getParameters());

        String methodType = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, node.getParameters());
        mv = cv.visitMethod(node.getModifiers(), "<init>", methodType, null, null);
        mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
        mv.visitInsn(DUP);
        mv.visitLdcInsn("not intended for execution");
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false);
        mv.visitInsn(ATHROW);
        mv.visitMaxs(0, 0);
    }

    public void visitMethod(MethodNode node) {

        visitParameters(node, node.getParameters());

        String methodType = BytecodeHelper.getMethodDescriptor(node.getReturnType(), node.getParameters());
        mv = cv.visitMethod(node.getModifiers(), node.getName(), methodType, null, null);

        mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
        mv.visitInsn(DUP);
        mv.visitLdcInsn("not intended for execution");
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false);
        mv.visitInsn(ATHROW);

        mv.visitMaxs(0, 0);
    }

    public void visitField(FieldNode fieldNode) {

        cv.visitField(
                fieldNode.getModifiers(),
                fieldNode.getName(),
                BytecodeHelper.getTypeDescription(fieldNode.getType()),
                null, //fieldValue,  //br  all the sudden that one cannot init the field here. init is done in static initializer and instance initializer.
                null);
    }

    /**
     * Creates a getter, setter and field
     */
    public void visitProperty(PropertyNode statement) {
    }

    protected CompileUnit getCompileUnit() {
        CompileUnit answer = classNode.getCompileUnit();
        if (answer == null) {
            answer = context.getCompileUnit();
        }
        return answer;
    }

    protected void visitParameters(ASTNode node, Parameter[] parameters) {
        for (Parameter parameter : parameters) {
            visitParameter(node, parameter);
        }
    }

    protected void visitParameter(ASTNode node, Parameter parameter) {
    }


    public void visitAnnotations(AnnotatedNode node) {
    }
}
