/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
 *
 * 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.android.ide.eclipse.adt.internal.editors.layout;

import static com.android.SdkConstants.ANDROID_PKG_PREFIX;
import static com.android.SdkConstants.CALENDAR_VIEW;
import static com.android.SdkConstants.CLASS_VIEW;
import static com.android.SdkConstants.EXPANDABLE_LIST_VIEW;
import static com.android.SdkConstants.FQCN_GRID_VIEW;
import static com.android.SdkConstants.FQCN_SPINNER;
import static com.android.SdkConstants.GRID_VIEW;
import static com.android.SdkConstants.LIST_VIEW;
import static com.android.SdkConstants.SPINNER;
import static com.android.SdkConstants.VIEW_FRAGMENT;
import static com.android.SdkConstants.VIEW_INCLUDE;

import com.android.SdkConstants;
import com.android.ide.common.rendering.LayoutLibrary;
import com.android.ide.common.rendering.RenderSecurityManager;
import com.android.ide.common.rendering.api.ActionBarCallback;
import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.DataBindingItem;
import com.android.ide.common.rendering.api.Features;
import com.android.ide.common.rendering.api.ILayoutPullParser;
import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.resources.ResourceResolver;
import com.android.ide.common.xml.ManifestData;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.LayoutMetadata;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderLogger;
import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
import com.android.ide.eclipse.adt.internal.resources.manager.ProjectClassLoader;
import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
import com.android.resources.ResourceType;
import com.android.util.Pair;
import com.google.common.base.Charsets;
import com.google.common.io.Files;

import org.eclipse.core.resources.IProject;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

/**
 * Loader for Android Project class in order to use them in the layout editor.
 * <p/>This implements {@link IProjectCallback} for the old and new API through
 * {@link LayoutlibCallback}
 */
public final class ProjectCallback extends LayoutlibCallback {
    private final HashMap<String, Class<?>> mLoadedClasses = new HashMap<String, Class<?>>();
    private final Set<String> mMissingClasses = new TreeSet<String>();
    private final Set<String> mBrokenClasses = new TreeSet<String>();
    private final IProject mProject;
    private final ClassLoader mParentClassLoader;
    private final ProjectResources mProjectRes;
    private final Object mCredential;
    private boolean mUsed = false;
    private String mNamespace;
    private ProjectClassLoader mLoader = null;
    private LayoutLog mLogger;
    private LayoutLibrary mLayoutLib;
    private String mLayoutName;
    private ILayoutPullParser mLayoutEmbeddedParser;
    private ResourceResolver mResourceResolver;
    private GraphicalEditorPart mEditor;

    /**
     * Creates a new {@link ProjectCallback} to be used with the layout lib.
     *
     * @param layoutLib The layout library this callback is going to be invoked from
     * @param projectRes the {@link ProjectResources} for the project.
     * @param project the project.
     * @param credential the sandbox credential
     */
    public ProjectCallback(LayoutLibrary layoutLib,
            ProjectResources projectRes, IProject project, Object credential,
            GraphicalEditorPart editor) {
        mLayoutLib = layoutLib;
        mParentClassLoader = layoutLib.getClassLoader();
        mProjectRes = projectRes;
        mProject = project;
        mCredential = credential;
        mEditor = editor;
    }

    public Set<String> getMissingClasses() {
        return mMissingClasses;
    }

    public Set<String> getUninstantiatableClasses() {
        return mBrokenClasses;
    }

    /**
     * Sets the {@link LayoutLog} logger to use for error messages during problems
     *
     * @param logger the new logger to use, or null to clear it out
     */
    public void setLogger(LayoutLog logger) {
        mLogger = logger;
    }

    /**
     * Returns the {@link LayoutLog} logger used for error messages, or null
     *
     * @return the logger being used, or null if no logger is in use
     */
    public LayoutLog getLogger() {
        return mLogger;
    }

    /**
     * {@inheritDoc}
     *
     * This implementation goes through the output directory of the Eclipse project and loads the
     * <code>.class</code> file directly.
     */
    @Override
    @SuppressWarnings("unchecked")
    public Object loadView(String className, Class[] constructorSignature,
            Object[] constructorParameters)
            throws Exception {
        mUsed = true;

        if (className == null) {
            // Just make a plain <View> if you specify <view> without a class= attribute.
            className = CLASS_VIEW;
        }

        // look for a cached version
        Class<?> clazz = mLoadedClasses.get(className);
        if (clazz != null) {
            return instantiateClass(clazz, constructorSignature, constructorParameters);
        }

        // load the class.

        try {
            if (mLoader == null) {
                // Allow creating class loaders during rendering; may be prevented by the
                // RenderSecurityManager
                boolean token = RenderSecurityManager.enterSafeRegion(mCredential);
                try {
                  mLoader = new ProjectClassLoader(mParentClassLoader, mProject);
                } finally {
                    RenderSecurityManager.exitSafeRegion(token);
                }
            }
            clazz = mLoader.loadClass(className);
        } catch (Exception e) {
            // Add the missing class to the list so that the renderer can print them later.
            // no need to log this.
            if (!className.equals(VIEW_FRAGMENT) && !className.equals(VIEW_INCLUDE)) {
                mMissingClasses.add(className);
            }
        }

        try {
            if (clazz != null) {
                // first try to instantiate it because adding it the list of loaded class so that
                // we don't add broken classes.
                Object view = instantiateClass(clazz, constructorSignature, constructorParameters);
                mLoadedClasses.put(className, clazz);

                return view;
            }
        } catch (Throwable e) {
            // Find root cause to log it.
            while (e.getCause() != null) {
                e = e.getCause();
            }

            appendToIdeLog(e, "%1$s failed to instantiate.", className); //$NON-NLS-1$

            // Add the missing class to the list so that the renderer can print them later.
            if (mLogger instanceof RenderLogger) {
                RenderLogger renderLogger = (RenderLogger) mLogger;
                renderLogger.recordThrowable(e);

            }
            mBrokenClasses.add(className);
        }

        // Create a mock view instead. We don't cache it in the mLoadedClasses map.
        // If any exception is thrown, we'll return a CFN with the original class name instead.
        try {
            clazz = mLoader.loadClass(SdkConstants.CLASS_MOCK_VIEW);
            Object view = instantiateClass(clazz, constructorSignature, constructorParameters);

            // Set the text of the mock view to the simplified name of the custom class
            Method m = view.getClass().getMethod("setText",
                                                 new Class<?>[] { CharSequence.class });
            String label = getShortClassName(className);
            if (label.equals(VIEW_FRAGMENT)) {
                label = "<fragment>\n"
                        + "Pick preview layout from the \"Fragment Layout\" context menu";
            } else if (label.equals(VIEW_INCLUDE)) {
                label = "Text";
            }

            m.invoke(view, label);

            // Call MockView.setGravity(Gravity.CENTER) to get the text centered in
            // MockViews.
            // TODO: Do this in layoutlib's MockView class instead.
            try {
                // Look up android.view.Gravity#CENTER - or can we just hard-code
                // the value (17) here?
                Class<?> gravity =
                    Class.forName("android.view.Gravity", //$NON-NLS-1$
                            true, view.getClass().getClassLoader());
                Field centerField = gravity.getField("CENTER"); //$NON-NLS-1$
                int center = centerField.getInt(null);
                m = view.getClass().getMethod("setGravity",
                        new Class<?>[] { Integer.TYPE });
                // Center
                //int center = (0x0001 << 4) | (0x0001 << 0);
                m.invoke(view, Integer.valueOf(center));
            } catch (Exception e) {
                // Not important to center views
            }

            return view;
        } catch (Exception e) {
            // We failed to create and return a mock view.
            // Just throw back a CNF with the original class name.
            throw new ClassNotFoundException(className, e);
        }
    }

    private String getShortClassName(String fqcn) {
        // The name is typically a fully-qualified class name. Let's make it a tad shorter.

        if (fqcn.startsWith("android.")) {                                      //$NON-NLS-1$
            // For android classes, convert android.foo.Name to android...Name
            int first = fqcn.indexOf('.');
            int last = fqcn.lastIndexOf('.');
            if (last > first) {
                return fqcn.substring(0, first) + ".." + fqcn.substring(last);   //$NON-NLS-1$
            }
        } else {
            // For custom non-android classes, it's best to keep the 2 first segments of
            // the namespace, e.g. we want to get something like com.example...MyClass
            int first = fqcn.indexOf('.');
            first = fqcn.indexOf('.', first + 1);
            int last = fqcn.lastIndexOf('.');
            if (last > first) {
                return fqcn.substring(0, first) + ".." + fqcn.substring(last);   //$NON-NLS-1$
            }
        }

        return fqcn;
    }

    /**
     * Returns the namespace for the project. The namespace contains a standard part + the
     * application package.
     *
     * @return The package namespace of the project or null in case of error.
     */
    @Override
    public String getNamespace() {
        if (mNamespace == null) {
            boolean token = RenderSecurityManager.enterSafeRegion(mCredential);
            try {
                ManifestData manifestData = AndroidManifestHelper.parseForData(mProject);
                if (manifestData != null) {
                    String javaPackage = manifestData.getPackage();
                    mNamespace = String.format(AdtConstants.NS_CUSTOM_RESOURCES, javaPackage);
                }
            } finally {
                RenderSecurityManager.exitSafeRegion(token);
            }
        }

        return mNamespace;
    }

    @Override
    public Pair<ResourceType, String> resolveResourceId(int id) {
        if (mProjectRes != null) {
            return mProjectRes.resolveResourceId(id);
        }

        return null;
    }

    @Override
    public String resolveResourceId(int[] id) {
        if (mProjectRes != null) {
            return mProjectRes.resolveStyleable(id);
        }

        return null;
    }

    @Override
    public Integer getResourceId(ResourceType type, String name) {
        if (mProjectRes != null) {
            return mProjectRes.getResourceId(type, name);
        }

        return null;
    }

    /**
     * Returns whether the loader has received requests to load custom views. Note that
     * the custom view loading may not actually have succeeded; this flag only records
     * whether it was <b>requested</b>.
     * <p/>
     * This allows to efficiently only recreate when needed upon code change in the
     * project.
     *
     * @return true if the loader has been asked to load custom views
     */
    public boolean isUsed() {
        return mUsed;
    }

    /**
     * Instantiate a class object, using a specific constructor and parameters.
     * @param clazz the class to instantiate
     * @param constructorSignature the signature of the constructor to use
     * @param constructorParameters the parameters to use in the constructor.
     * @return A new class object, created using a specific constructor and parameters.
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    private Object instantiateClass(Class<?> clazz,
            Class[] constructorSignature,
            Object[] constructorParameters) throws Exception {
        Constructor<?> constructor = null;

        try {
            constructor = clazz.getConstructor(constructorSignature);

        } catch (NoSuchMethodException e) {
            // Custom views can either implement a 3-parameter, 2-parameter or a
            // 1-parameter. Let's synthetically build and try all the alternatives.
            // That's kind of like switching to the other box.
            //
            // The 3-parameter constructor takes the following arguments:
            // ...(Context context, AttributeSet attrs, int defStyle)

            int n = constructorSignature.length;
            if (n == 0) {
                // There is no parameter-less constructor. Nobody should ask for one.
                throw e;
            }

            for (int i = 3; i >= 1; i--) {
                if (i == n) {
                    // Let's skip the one we know already fails
                    continue;
                }
                Class[] sig = new Class[i];
                Object[] params = new Object[i];

                int k = i;
                if (n < k) {
                    k = n;
                }
                System.arraycopy(constructorSignature, 0, sig, 0, k);
                System.arraycopy(constructorParameters, 0, params, 0, k);

                for (k++; k <= i; k++) {
                    if (k == 2) {
                        // Parameter 2 is the AttributeSet
                        sig[k-1] = clazz.getClassLoader().loadClass("android.util.AttributeSet");
                        params[k-1] = null;

                    } else if (k == 3) {
                        // Parameter 3 is the int defstyle
                        sig[k-1] = int.class;
                        params[k-1] = 0;
                    }
                }

                constructorSignature = sig;
                constructorParameters = params;

                try {
                    // Try again...
                    constructor = clazz.getConstructor(constructorSignature);
                    if (constructor != null) {
                        // Found a suitable constructor, now let's use it.
                        // (But let's warn the user if the simple View constructor was found
                        // since Unexpected Things may happen if the attribute set constructors
                        // are not found)
                        if (constructorSignature.length < 2 && mLogger != null) {
                            mLogger.warning("wrongconstructor", //$NON-NLS-1$
                                String.format("Custom view %1$s is not using the 2- or 3-argument "
                                    + "View constructors; XML attributes will not work",
                                    clazz.getSimpleName()), null /*data*/);
                        }
                        break;
                    }
                } catch (NoSuchMethodException e1) {
                    // pass
                }
            }

            // If all the alternatives failed, throw the initial exception.
            if (constructor == null) {
                throw e;
            }
        }

        constructor.setAccessible(true);
        return constructor.newInstance(constructorParameters);
    }

    public void setLayoutParser(String layoutName, ILayoutPullParser layoutParser) {
        mLayoutName = layoutName;
        mLayoutEmbeddedParser = layoutParser;
    }

    @Override
    public ILayoutPullParser getParser(String layoutName) {
        boolean token = RenderSecurityManager.enterSafeRegion(mCredential);
        try {
            // Try to compute the ResourceValue for this layout since layoutlib
            // must be an older version which doesn't pass the value:
            if (mResourceResolver != null) {
                ResourceValue value = mResourceResolver.getProjectResource(ResourceType.LAYOUT,
                        layoutName);
                if (value != null) {
                    return getParser(value);
                }
            }

            return getParser(layoutName, null);
        } finally {
            RenderSecurityManager.exitSafeRegion(token);
        }
    }

    @Override
    public ILayoutPullParser getParser(ResourceValue layoutResource) {
        boolean token = RenderSecurityManager.enterSafeRegion(mCredential);
        try {
            return getParser(layoutResource.getName(),
                    new File(layoutResource.getValue()));
        } finally {
            RenderSecurityManager.exitSafeRegion(token);
        }
    }

    private ILayoutPullParser getParser(String layoutName, File xml) {
        if (layoutName.equals(mLayoutName)) {
            ILayoutPullParser parser = mLayoutEmbeddedParser;
            // The parser should only be used once!! If it is included more than once,
            // subsequent includes should just use a plain pull parser that is not tied
            // to the XML model
            mLayoutEmbeddedParser = null;
            return parser;
        }

        // For included layouts, create a ContextPullParser such that we get the
        // layout editor behavior in included layouts as well - which for example
        // replaces <fragment> tags with <include>.
        if (xml != null && xml.isFile()) {
            ContextPullParser parser = new ContextPullParser(this, xml);
            try {
                parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
                String xmlText = Files.toString(xml, Charsets.UTF_8);
                parser.setInput(new StringReader(xmlText));
                return parser;
            } catch (XmlPullParserException e) {
                appendToIdeLog(e, null);
            } catch (FileNotFoundException e) {
                // Shouldn't happen since we check isFile() above
            } catch (IOException e) {
                appendToIdeLog(e, null);
            }
        }

        return null;
    }

    @Override
    public Object getAdapterItemValue(ResourceReference adapterView, Object adapterCookie,
            ResourceReference itemRef,
            int fullPosition, int typePosition, int fullChildPosition, int typeChildPosition,
            ResourceReference viewRef, ViewAttribute viewAttribute, Object defaultValue) {

        // Special case for the palette preview
        if (viewAttribute == ViewAttribute.TEXT
                && adapterView.getName().startsWith("android_widget_")) { //$NON-NLS-1$
            String name = adapterView.getName();
            if (viewRef.getName().equals("text2")) { //$NON-NLS-1$
                return "Sub Item";
            }
            if (fullPosition == 0) {
                String viewName = name.substring("android_widget_".length());
                if (viewName.equals(EXPANDABLE_LIST_VIEW)) {
                    return "ExpandableList"; // ExpandableListView is too wide, character-wraps
                }
                return viewName;
            } else {
                return "Next Item";
            }
        }

        if (itemRef.isFramework()) {
            // Special case for list_view_item_2 and friends
            if (viewRef.getName().equals("text2")) { //$NON-NLS-1$
                return "Sub Item " + (fullPosition + 1);
            }
        }

        if (viewAttribute == ViewAttribute.TEXT && ((String) defaultValue).length() == 0) {
            return "Item " + (fullPosition + 1);
        }

        return null;
    }

    /**
     * For the given class, finds and returns the nearest super class which is a ListView
     * or an ExpandableListView or a GridView (which uses a list adapter), or returns null.
     *
     * @param clz the class of the view object
     * @return the fully qualified class name of the list ancestor, or null if there
     *         is no list view ancestor
     */
    public static String getListAdapterViewFqcn(Class<?> clz) {
        String fqcn = clz.getName();
        if (fqcn.endsWith(LIST_VIEW)) { // including EXPANDABLE_LIST_VIEW
            return fqcn;
        } else if (fqcn.equals(FQCN_GRID_VIEW)) {
            return fqcn;
        } else if (fqcn.equals(FQCN_SPINNER)) {
            return fqcn;
        } else if (fqcn.startsWith(ANDROID_PKG_PREFIX)) {
            return null;
        }
        Class<?> superClass = clz.getSuperclass();
        if (superClass != null) {
            return getListAdapterViewFqcn(superClass);
        } else {
            // Should not happen; we would have encountered android.view.View first,
            // and it should have been covered by the ANDROID_PKG_PREFIX case above.
            return null;
        }
    }

    /**
     * Looks at the parent-chain of the view and if it finds a custom view, or a
     * CalendarView, within the given distance then it returns true. A ListView within a
     * CalendarView should not be assigned a custom list view type because it sets its own
     * and then attempts to cast the layout to its own type which would fail if the normal
     * default list item binding is used.
     */
    private boolean isWithinIllegalParent(Object viewObject, int depth) {
        String fqcn = viewObject.getClass().getName();
        if (fqcn.endsWith(CALENDAR_VIEW) || !fqcn.startsWith(ANDROID_PKG_PREFIX)) {
            return true;
        }

        if (depth > 0) {
            Result result = mLayoutLib.getViewParent(viewObject);
            if (result.isSuccess()) {
                Object parent = result.getData();
                if (parent != null) {
                    return isWithinIllegalParent(parent, depth -1);
                }
            }
        }

        return false;
    }

    @Override
    public AdapterBinding getAdapterBinding(final ResourceReference adapterView,
            final Object adapterCookie, final Object viewObject) {
        // Look for user-recorded preference for layout to be used for previews
        if (adapterCookie instanceof UiViewElementNode) {
            UiViewElementNode uiNode = (UiViewElementNode) adapterCookie;
            AdapterBinding binding = LayoutMetadata.getNodeBinding(viewObject, uiNode);
            if (binding != null) {
                return binding;
            }
        } else if (adapterCookie instanceof Map<?,?>) {
            @SuppressWarnings("unchecked")
            Map<String, String> map = (Map<String, String>) adapterCookie;
            AdapterBinding binding = LayoutMetadata.getNodeBinding(viewObject, map);
            if (binding != null) {
                return binding;
            }
        }

        if (viewObject == null) {
            return null;
        }

        // Is this a ListView or ExpandableListView? If so, return its fully qualified
        // class name, otherwise return null. This is used to filter out other types
        // of AdapterViews (such as Spinners) where we don't want to use the list item
        // binding.
        String listFqcn = getListAdapterViewFqcn(viewObject.getClass());
        if (listFqcn == null) {
            return null;
        }

        // Is this ListView nested within an "illegal" container, such as a CalendarView?
        // If so, don't change the bindings below. Some views, such as CalendarView, and
        // potentially some custom views, might be doing specific things with the ListView
        // that could break if we add our own list binding, so for these leave the list
        // alone.
        if (isWithinIllegalParent(viewObject, 2)) {
            return null;
        }

        int count = listFqcn.endsWith(GRID_VIEW) ? 24 : 12;
        AdapterBinding binding = new AdapterBinding(count);
        if (listFqcn.endsWith(EXPANDABLE_LIST_VIEW)) {
            binding.addItem(new DataBindingItem(LayoutMetadata.DEFAULT_EXPANDABLE_LIST_ITEM,
                    true /* isFramework */, 1));
        } else if (listFqcn.equals(SPINNER)) {
            binding.addItem(new DataBindingItem(LayoutMetadata.DEFAULT_SPINNER_ITEM,
                    true /* isFramework */, 1));
        } else {
            binding.addItem(new DataBindingItem(LayoutMetadata.DEFAULT_LIST_ITEM,
                    true /* isFramework */, 1));
        }

        return binding;
    }

    /**
     * Sets the {@link ResourceResolver} to be used when looking up resources
     *
     * @param resolver the resolver to use
     */
    public void setResourceResolver(ResourceResolver resolver) {
        mResourceResolver = resolver;
    }

    // Append the given message to the ADT log. Bypass the sandbox if necessary
    // such that we can write to the log file.
    private void appendToIdeLog(Throwable exception, String format, Object ... args) {
        boolean token = RenderSecurityManager.enterSafeRegion(mCredential);
        try {
            AdtPlugin.log(exception, format, args);
        } finally {
            RenderSecurityManager.exitSafeRegion(token);
        }
    }

    @Override
    public ActionBarCallback getActionBarCallback() {
        return new ActionBarHandler(mEditor);
    }

    @Override
    public boolean supports(int feature) {
        return feature <= Features.LAST_CAPABILITY;
    }
}
