/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * 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 com.motorola.studio.android.generateviewbylayout;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;

import com.motorola.studio.android.codeutils.i18n.CodeUtilsNLS;
import com.motorola.studio.android.generatecode.BasicCodeVisitor;
import com.motorola.studio.android.generateviewbylayout.model.CodeGeneratorDataBasedOnLayout;
import com.motorola.studio.android.generateviewbylayout.model.LayoutNode;

/**
 * Visitor for class method declarations to find onCreate methods inside activity / fragment.
 * It calls BodyVisitor to continue extracting information about the Android code.
 */
public class GenerateCodeBasedOnLayoutVisitor extends BasicCodeVisitor
{
    /*
     * Constants 
     */
    private static final String ACTIVITY_ON_CREATE_DECLARATION = "void onCreate(android.os.Bundle)"; //$NON-NLS-1$

    private static final String FRAGMENT_ON_CREATE_DECLARATION =
            "android.view.View onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)"; //$NON-NLS-1$

    private static final String ACTIVITY_ON_CREATE = "onCreate"; //$NON-NLS-1$

    private static final String FRAGMENT_ON_CREATE = "onCreateView"; //$NON-NLS-1$

    private static final String ACTIVITY_ON_PAUSE_DECLARATION = "void onPause()";

    private static final String ACTIVITY_ON_RESUME_DECLARATION = "void onResume()";

    private static final String ACTIVITY_ON_PAUSE = "onPause";

    private static final String ACTIVITY_ON_RESUME = "onResume";

    private MethodDeclaration onCreateDeclaration;

    private CodeGeneratorDataBasedOnLayout.TYPE typeAssociatedToLayout;

    /**
     * If type is fragment, there may be an inflated view name.
     * This will be used to call findViewById inside fragments  
     */
    private String inflatedViewName;

    private final Set<String> declaredViewIds = new HashSet<String>();

    private final Set<String> savedViewIds = new HashSet<String>();

    private final Set<String> restoredViewIds = new HashSet<String>();

    private String layoutName;

    /**
     * @return method declaration reference if there an onCreate method declared, null if not found
     */
    public MethodDeclaration getOnCreateDeclaration()
    {
        return onCreateDeclaration;
    }

    public void setOnCreateDeclaration(MethodDeclaration onCreateDeclaration)
    {

        this.onCreateDeclaration = onCreateDeclaration;
    }

    /**
     * @return name of the layout being visited
     */
    public String getLayoutName()
    {
        return layoutName;
    }

    public void setLayoutName(String layoutName)
    {
        this.layoutName = layoutName;
    }

    /**
     * Visit method declaration, searching for instructions 
     * onCreate for activity or fragment
     */
    @Override
    public boolean visit(MethodDeclaration node)
    {
        //Fill Method information
        SimpleName name = node.getName();
        if (name.getIdentifier().equals(ACTIVITY_ON_CREATE)
                || name.getIdentifier().equals(FRAGMENT_ON_CREATE))
        {
            IMethodBinding binding = node.resolveBinding();
            if (binding != null)
            {
                if (binding.toString().trim().contains(ACTIVITY_ON_CREATE_DECLARATION))
                {
                    visitMethodBodyToIdentifyLayout(node);
                }
                else if (binding.toString().trim().contains(FRAGMENT_ON_CREATE_DECLARATION))
                {
                    if (node.getBody().statements().size() <= 1)
                    {
                        throw new IllegalArgumentException(
                                CodeUtilsNLS.MethodVisitor_InvalidFormatForFragmentOnCreateView);
                    }
                    else
                    {
                        visitMethodBodyToIdentifyLayout(node);
                    }
                }
                else
                {
                    //for each method visit to identify views already declared
                    visitToIdentifyViewsAlreadyDeclared(node);
                }
            }
        }
        else if (name.getIdentifier().equals(ACTIVITY_ON_PAUSE)
                || name.getIdentifier().equals(ACTIVITY_ON_RESUME))
        {
            IMethodBinding binding = node.resolveBinding();
            if (binding != null)
            {
                //find declared save state
                if (binding.toString().trim().contains(ACTIVITY_ON_PAUSE_DECLARATION))
                {
                    findSavedViews(node);
                }
                //find declared restore state
                else if (binding.toString().trim().contains(ACTIVITY_ON_RESUME_DECLARATION))
                {
                    findRestoredViews(node);
                }

            }
        }
        else
        {
            //for each method visit to identify views already declared
            visitToIdentifyViewsAlreadyDeclared(node);
        }
        return super.visit(node);
    }

    private void findRestoredViews(MethodDeclaration node)
    {
        SaveStateVisitor visitor = new SaveStateVisitor();
        node.accept(visitor);
        restoredViewIds.addAll(visitor.getViewIds());
    }

    private void findSavedViews(MethodDeclaration node)
    {
        SaveStateVisitor visitor = new SaveStateVisitor();
        node.accept(visitor);
        savedViewIds.addAll(visitor.getViewIds());
    }

    /**
     * @param node
     */
    protected synchronized void visitToIdentifyViewsAlreadyDeclared(MethodDeclaration node)
    {
        Block body = node.getBody();
        if (body != null)
        {
            MethodBodyVisitor visitor = new MethodBodyVisitor();
            visitAndUpdateDeclaredViewsBasedOnFindViewById(body, visitor);
        }
    }

    /**
     * Visit method body from onCreate declaration to identify layout used
     * (it also verifies views already declared)
     * @param node
     * @throws JavaModelException 
     */
    protected void visitMethodBodyToIdentifyLayout(MethodDeclaration node)
    {
        //Navigate through statements...
        setOnCreateDeclaration(node);
        Block body = node.getBody();
        if (body != null)
        {
            identifyLayout(body);
        }
    }

    /**
     * Navigates in a Block and extract layout name, if class associated to layout is activity or fragment, 
     * and, in case of fragment only, the name of the view inflated.
     */
    private void identifyLayout(Block body)
    {
        MethodBodyVisitor visitor = new MethodBodyVisitor();
        visitAndUpdateDeclaredViewsBasedOnFindViewById(body, visitor);
        setLayoutName(visitor.getLayoutName());
        typeAssociatedToLayout = visitor.getTypeAssociatedToLayout();
        setInflatedViewName(visitor.getInflatedViewName());
    }

    /**
     * Visit method body to identify view ids already declared
     * @param body
     * @param visitor
     */
    public void visitAndUpdateDeclaredViewsBasedOnFindViewById(Block body, MethodBodyVisitor visitor)
    {
        body.accept(visitor);
        synchronized (declaredViewIds)
        {
            declaredViewIds.addAll(visitor.getDeclaredViewIds());
        }

    }

    /**
     * Check if there is an attribute already declared with the name given.
     * @param node
     * @param considerType false, if must not consider the type in the analysis  
     * @return true if there a variable declared with the node.getNodeId() independent on variable type,
     * false otherwise
     */
    public boolean checkIfAttributeAlreadyDeclared(LayoutNode node, boolean considerType)
    {
        boolean containFieldDeclared = false;
        if (typeDeclaration.bodyDeclarations() != null)
        {
            //check if attribute already declared                  
            for (Object bd : typeDeclaration.bodyDeclarations())
            {
                if (bd instanceof FieldDeclaration)
                {
                    FieldDeclaration fd = (FieldDeclaration) bd;
                    if (fd.getParent() instanceof TypeDeclaration)
                    {
                        TypeDeclaration type = (TypeDeclaration) fd.getParent();
                        if (typeDeclaration.equals(type))
                        {
                            //only considers attributes from main class inside the file
                            for (Object fragment : fd.fragments())
                            {
                                if (fragment instanceof VariableDeclarationFragment)
                                {
                                    VariableDeclarationFragment frag =
                                            (VariableDeclarationFragment) fragment;
                                    if ((frag.getName() != null)
                                            && frag.getName().toString().equals(node.getNodeId()))
                                    {
                                        if (considerType)
                                        {
                                            if ((fd.getType() != null)
                                                    && !fd.getType().toString()
                                                            .equals(node.getNodeType()))
                                            {
                                                containFieldDeclared = true;
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            containFieldDeclared = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return containFieldDeclared;
    }

    /**
     * @return the typeAssociatedToLayout
     */
    public CodeGeneratorDataBasedOnLayout.TYPE getTypeAssociatedToLayout()
    {
        return typeAssociatedToLayout;
    }

    /**
     * @return the inflatedViewName
     */
    public String getInflatedViewName()
    {
        return inflatedViewName;
    }

    /**
     * @param inflatedViewName the inflatedViewName to set
     */
    public void setInflatedViewName(String inflatedViewName)
    {
        this.inflatedViewName = inflatedViewName;
    }

    /**
     * @return the list of declared layout ids (as specified in layout.xml under android:id attribute)
     */
    public synchronized Set<String> getDeclaredViewIds()
    {
        return declaredViewIds;
    }

    /**
     * @return the list of view ids that have code to restore state (using SharedPreferences)
     */
    public Set<String> getRestoredViewIds()
    {
        return restoredViewIds;
    }

    /**
     * @return the list of view ids that have code to save state (using SharedPreferences)
     */
    public Set<String> getSavedViewIds()
    {
        return savedViewIds;
    }

}
