/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015-2019 Stephan Pauxberger
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.blackbuild.groovy.configdsl.transform.ast;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.expr.ListExpression;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.transform.AbstractASTTransformation;
import org.codehaus.groovy.transform.GroovyASTTransformation;

import java.util.ArrayList;
import java.util.List;

import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;

/**
 * Transformation that adds relevant annotations to the generated files.
 */
@GroovyASTTransformation(phase = CompilePhase.INSTRUCTION_SELECTION)
public class AddJacksonIgnoresTransformation extends AbstractASTTransformation {

    private ClassNode annotatedClass;
    private ClassNode jsonIngoreType;

    @Override
    public void visit(ASTNode[] nodes, SourceUnit source) {

        try {
            jsonIngoreType = ClassHelper.make(Class.forName("com.fasterxml.jackson.annotation.JsonIgnoreProperties"));
        } catch (ClassNotFoundException ignored) {
            // No jackson in classpath
            return;
        }

        init(nodes, source);

        annotatedClass = (ClassNode) nodes[1];

        if (annotatedClass.isInterface())
            return;

        List<String> fieldsToIgnore = new ArrayList<>();

        fieldsToIgnore.add("$key");
        fieldsToIgnore.addAll(DslAstHelper.getOwnerFieldNames(annotatedClass));

        addIgnoreAnnotation(fieldsToIgnore);
    }

    void addIgnoreAnnotation(List<String> propertiesToIgnore) {
        ListExpression ignoreArguments = new ListExpression();

        for (String property : propertiesToIgnore) {
            ignoreArguments.addExpression(constX(property));
        }

        AnnotationNode ignoreAnnotation = new AnnotationNode(jsonIngoreType);
        ignoreAnnotation.addMember("value", ignoreArguments);
        annotatedClass.addAnnotation(ignoreAnnotation);
    }

}

@@ -1375,24 +1375,66 @@
 .ClassNode;%0A
+import org.codehaus.groovy.ast.FieldNode;%0A
 import org.c
@@ -1717,42 +1717,172 @@
 til.
-ArrayList;%0Aimport java.util.List;%0A
+Collection;%0Aimport java.util.HashSet;%0Aimport java.util.Set;%0A%0Aimport static com.blackbuild.groovy.configdsl.transform.ast.DslAstHelper.getAnnotatedFieldsOfHierarchy;
 %0Aimp
@@ -2731,19 +2731,18 @@
         
-Lis
+Se
 t%3CString
@@ -2768,16 +2768,14 @@
 new 
-ArrayLis
+HashSe
 t%3C%3E(
@@ -2827,78 +2827,184 @@
    f
-ieldsToIgnore.addAll(DslAstHelper.getOwnerFieldNames(annotatedClass));
+or (FieldNode fieldNode : getAnnotatedFieldsOfHierarchy(annotatedClass, DSLASTTransformation.OWNER_ANNOTATION)) %7B%0A            fieldsToIgnore.add(fieldNode.getName());%0A        %7D
 %0A%0A  
@@ -3082,20 +3082,26 @@
 otation(
-List
+Collection
 %3CString%3E

Fix json annotations with owner fields