/*
 *  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.transform;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotatedNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.FieldNode;
import org.codehaus.groovy.ast.InnerClassNode;
import org.codehaus.groovy.ast.Parameter;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.expr.EmptyExpression;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.ast.stmt.BlockStatement;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.ast.stmt.SynchronizedStatement;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.runtime.MetaClassHelper;

import java.lang.ref.SoftReference;

import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching;
import static org.codehaus.groovy.ast.tools.GeneralUtils.assignS;
import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.classX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.declS;
import static org.codehaus.groovy.ast.tools.GeneralUtils.ifElseS;
import static org.codehaus.groovy.ast.tools.GeneralUtils.notNullX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.param;
import static org.codehaus.groovy.ast.tools.GeneralUtils.params;
import static org.codehaus.groovy.ast.tools.GeneralUtils.propX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS;
import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;

/**
 * Handles generation of code for the @Lazy annotation
 */
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
public class LazyASTTransformation extends AbstractASTTransformation {

    private static final ClassNode SOFT_REF = makeWithoutCaching(SoftReference.class, false);
    private static final Expression NULL_EXPR = ConstantExpression.NULL;

    public void visit(ASTNode[] nodes, SourceUnit source) {
        init(nodes, source);
        AnnotatedNode parent = (AnnotatedNode) nodes[1];
        AnnotationNode node = (AnnotationNode) nodes[0];

        if (parent instanceof FieldNode) {
            final FieldNode fieldNode = (FieldNode) parent;
            visitField(this, node, fieldNode);
        }
    }

    static void visitField(ErrorCollecting xform, AnnotationNode node, FieldNode fieldNode) {
        final Expression soft = node.getMember("soft");
        final Expression init = getInitExpr(xform, fieldNode);

        fieldNode.rename("$" + fieldNode.getName());
        fieldNode.setModifiers(ACC_PRIVATE | (fieldNode.getModifiers() & (~(ACC_PUBLIC | ACC_PROTECTED))));

        if (soft instanceof ConstantExpression && ((ConstantExpression) soft).getValue().equals(true)) {
            createSoft(fieldNode, init);
        } else {
            create(fieldNode, init);
            // @Lazy not meaningful with primitive so convert to wrapper if needed
            if (ClassHelper.isPrimitiveType(fieldNode.getType())) {
                fieldNode.setType(ClassHelper.getWrapper(fieldNode.getType()));
            }
        }
    }

    private static void create(FieldNode fieldNode, final Expression initExpr) {
        final BlockStatement body = new BlockStatement();
        if (fieldNode.isStatic()) {
            addHolderClassIdiomBody(body, fieldNode, initExpr);
        } else if (fieldNode.isVolatile()) {
            addDoubleCheckedLockingBody(body, fieldNode, initExpr);
        } else {
            addNonThreadSafeBody(body, fieldNode, initExpr);
        }
        addMethod(fieldNode, body, fieldNode.getType());
    }

    private static void addHolderClassIdiomBody(BlockStatement body, FieldNode fieldNode, Expression initExpr) {
        final ClassNode declaringClass = fieldNode.getDeclaringClass();
        final ClassNode fieldType = fieldNode.getType();
        final int visibility = ACC_PRIVATE | ACC_STATIC;
        final String fullName = declaringClass.getName() + "$" + fieldType.getNameWithoutPackage() + "Holder_" + fieldNode.getName().substring(1);
        final InnerClassNode holderClass = new InnerClassNode(declaringClass, fullName, visibility, ClassHelper.OBJECT_TYPE);
        final String innerFieldName = "INSTANCE";

        // we have two options:
        // (1) embed initExpr within holder class but redirect field access/method calls to declaring class members
        // (2) keep initExpr within a declaring class method that is only called by the holder class
        // currently we have gone with (2) for simplicity with only a slight memory footprint increase in the declaring class
        final String initializeMethodName = (fullName + "_initExpr").replace('.', '_');
        declaringClass.addMethod(initializeMethodName, ACC_PRIVATE | ACC_STATIC | ACC_FINAL, fieldType,
                Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, returnS(initExpr));
        holderClass.addField(innerFieldName, ACC_PRIVATE | ACC_STATIC | ACC_FINAL, fieldType,
                callX(declaringClass, initializeMethodName));

        final Expression innerField = propX(classX(holderClass), innerFieldName);
        declaringClass.getModule().addClass(holderClass);
        body.addStatement(returnS(innerField));
    }

    private static void addDoubleCheckedLockingBody(BlockStatement body, FieldNode fieldNode, Expression initExpr) {
        final Expression fieldExpr = varX(fieldNode);
        final VariableExpression localVar = varX(fieldNode.getName() + "_local");
        body.addStatement(declS(localVar, fieldExpr));
        body.addStatement(ifElseS(
                notNullX(localVar),
                returnS(localVar),
                new SynchronizedStatement(
                        syncTarget(fieldNode),
                        ifElseS(
                                notNullX(fieldExpr),
                                returnS(fieldExpr),
                                returnS(assignX(fieldExpr, initExpr))
                        )
                )
        ));
    }

    private static void addNonThreadSafeBody(BlockStatement body, FieldNode fieldNode, Expression initExpr) {
        final Expression fieldExpr = varX(fieldNode);
        body.addStatement(ifElseS(notNullX(fieldExpr), stmt(fieldExpr), assignS(fieldExpr, initExpr)));
    }

    private static void addMethod(FieldNode fieldNode, BlockStatement body, ClassNode type) {
        int visibility = ACC_PUBLIC;
        if (fieldNode.isStatic()) visibility |= ACC_STATIC;
        final String name = "get" + MetaClassHelper.capitalize(fieldNode.getName().substring(1));
        fieldNode.getDeclaringClass().addMethod(name, visibility, type, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, body);
    }

    private static void createSoft(FieldNode fieldNode, Expression initExpr) {
        final ClassNode type = fieldNode.getType();
        fieldNode.setType(SOFT_REF);
        createSoftGetter(fieldNode, initExpr, type);
        createSoftSetter(fieldNode, type);
    }

    private static void createSoftGetter(FieldNode fieldNode, Expression initExpr, ClassNode type) {
        final BlockStatement body = new BlockStatement();
        final Expression fieldExpr = varX(fieldNode);
        final Expression resExpr = varX("res", type);
        final MethodCallExpression callExpression = callX(fieldExpr, "get");
        callExpression.setSafe(true);
        body.addStatement(declS(resExpr, callExpression));

        final Statement mainIf = ifElseS(notNullX(resExpr), stmt(resExpr), block(
                assignS(resExpr, initExpr),
                assignS(fieldExpr, ctorX(SOFT_REF, resExpr)),
                stmt(resExpr)));

        if (fieldNode.isVolatile()) {
            body.addStatement(ifElseS(
                    notNullX(resExpr),
                    stmt(resExpr),
                    new SynchronizedStatement(syncTarget(fieldNode), block(
                            assignS(resExpr, callExpression),
                            mainIf)
                    )
            ));
        } else {
            body.addStatement(mainIf);
        }
        addMethod(fieldNode, body, type);
    }

    private static void createSoftSetter(FieldNode fieldNode, ClassNode type) {
        final BlockStatement body = new BlockStatement();
        final Expression fieldExpr = varX(fieldNode);
        final String name = "set" + MetaClassHelper.capitalize(fieldNode.getName().substring(1));
        final Parameter parameter = param(type, "value");
        final Expression paramExpr = varX(parameter);
        body.addStatement(ifElseS(
                notNullX(paramExpr),
                assignS(fieldExpr, ctorX(SOFT_REF, paramExpr)),
                assignS(fieldExpr, NULL_EXPR)
        ));
        int visibility = ACC_PUBLIC;
        if (fieldNode.isStatic()) visibility |= ACC_STATIC;
        fieldNode.getDeclaringClass().addMethod(name, visibility, ClassHelper.VOID_TYPE, params(parameter), ClassNode.EMPTY_ARRAY, body);
    }

    private static Expression syncTarget(FieldNode fieldNode) {
        return fieldNode.isStatic() ? classX(fieldNode.getDeclaringClass()) : varX("this");
    }

    private static Expression getInitExpr(ErrorCollecting xform, FieldNode fieldNode) {
        Expression initExpr = fieldNode.getInitialValueExpression();
        fieldNode.setInitialValueExpression(null);

        if (initExpr == null || initExpr instanceof EmptyExpression) {
            if (fieldNode.getType().isAbstract()) {
                xform.addError("You cannot lazily initialize '" + fieldNode.getName() + "' from the abstract class '" +
                        fieldNode.getType().getName() + "'", fieldNode);
            }
            initExpr = ctorX(fieldNode.getType());
        }

        return initExpr;
    }
}
