/*
 * Copyright (C) 2015 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.android.layoutlib.bridge.android.support;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.SessionParams;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.SessionParamsFlags;

import android.content.Context;
import android.view.View;
import android.widget.LinearLayout;

import java.lang.reflect.Method;
import java.util.HashMap;

import static com.android.layoutlib.bridge.util.ReflectionUtils.*;

/**
 * Utility class for working with android.support.v7.widget.RecyclerView
 */
@SuppressWarnings("SpellCheckingInspection")  // for "recycler".
public class RecyclerViewUtil {

    /**
     * Used by {@link LayoutManagerType}.
     * <p/>
     * Not declared inside the enum, since it needs to be accessible in the constructor.
     */
    private static final Object CONTEXT = new Object();

    public static final String CN_RECYCLER_VIEW = "android.support.v7.widget.RecyclerView";
    private static final String CN_LAYOUT_MANAGER = CN_RECYCLER_VIEW + "$LayoutManager";
    private static final String CN_ADAPTER = CN_RECYCLER_VIEW + "$Adapter";

    /**
     * Tries to create an Adapter ({@code android.support.v7.widget.RecyclerView.Adapter} and a
     * LayoutManager {@code RecyclerView.LayoutManager} and assign these to the {@code RecyclerView}
     * that is passed.
     * <p/>
     * Any exceptions thrown during the process are logged in {@link Bridge#getLog()}
     */
    public static void setAdapter(@NonNull View recyclerView, @NonNull BridgeContext context,
            @NonNull SessionParams params) {
        try {
            setLayoutManager(recyclerView, context, params.getProjectCallback());
            Object adapter = createAdapter(params);
            setProperty(recyclerView, CN_ADAPTER, adapter, "setAdapter");
        } catch (ReflectionException e) {
            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
                    "Error occured while trying to setup RecyclerView.", e, null);
        }
    }

    private static void setLayoutManager(@NonNull View recyclerView, @NonNull BridgeContext context,
            @NonNull IProjectCallback callback) throws ReflectionException {
        Object cookie = context.getCookie(recyclerView);
        assert cookie == null || cookie instanceof LayoutManagerType;
        if (cookie == null) {
            cookie = LayoutManagerType.getDefault();
        }
        Object layoutManager = createLayoutManager((LayoutManagerType) cookie, context, callback);
        setProperty(recyclerView, CN_LAYOUT_MANAGER, layoutManager, "setLayoutManager");
    }

    @Nullable
    private static Object createLayoutManager(@Nullable LayoutManagerType type,
            @NonNull Context context, @NonNull IProjectCallback callback)
            throws ReflectionException {
        if (type == null) {
            type = LayoutManagerType.getDefault();
        }
        try {
            return callback.loadView(type.getClassName(), type.getSignature(), type.getArgs(context));
        } catch (Exception e) {
            throw new ReflectionException(e);
        }
    }

    @Nullable
    private static Object createAdapter(@NonNull SessionParams params) throws ReflectionException {
        Boolean ideSupport = params.getFlag(SessionParamsFlags.FLAG_KEY_RECYCLER_VIEW_SUPPORT);
        if (ideSupport != Boolean.TRUE) {
            return null;
        }
        try {
            return params.getProjectCallback().loadView(CN_ADAPTER, new Class[0], new Object[0]);
        } catch (Exception e) {
            throw new ReflectionException(e);
        }
    }

    private static void setProperty(@NonNull View recyclerView, @NonNull String propertyClassName,
            @Nullable Object propertyValue, @NonNull String propertySetter)
            throws ReflectionException {
        if (propertyValue != null) {
            Class<?> layoutManagerClass = getClassInstance(propertyValue, propertyClassName);
            Method setLayoutManager = getMethod(recyclerView.getClass(),
                    propertySetter, layoutManagerClass);
            if (setLayoutManager != null) {
                invoke(setLayoutManager, recyclerView, propertyValue);
            }
        }
    }

    /**
     * Looks through the class hierarchy of {@code object} at runtime and returns the class matching
     * the name {@code className}.
     * <p/>
     * This is used when we cannot use Class.forName() since the class we want was loaded from a
     * different ClassLoader.
     */
    @NonNull
    private static Class<?> getClassInstance(@NonNull Object object, @NonNull String className) {
        Class<?> superClass = object.getClass();
        while (superClass != null) {
            if (className.equals(superClass.getName())) {
                return superClass;
            }
            superClass = superClass.getSuperclass();
        }
        throw new RuntimeException("invalid object/classname combination.");
    }

    /** Supported LayoutManagers. */
    public enum LayoutManagerType {
        LINEAR_LAYOUT_MANGER("Linear",
                "android.support.v7.widget.LinearLayoutManager",
                new Class[]{Context.class}, new Object[]{CONTEXT}),
        GRID_LAYOUT_MANAGER("Grid",
                "android.support.v7.widget.GridLayoutManager",
                new Class[]{Context.class, int.class}, new Object[]{CONTEXT, 2}),
        STAGGERED_GRID_LAYOUT_MANAGER("StaggeredGrid",
                "android.support.v7.widget.StaggeredGridLayoutManager",
                new Class[]{int.class, int.class}, new Object[]{2, LinearLayout.VERTICAL});

        private String mDisplayName;
        private String mClassName;
        private Class[] mSignature;
        private Object[] mArgs;

        private static final HashMap<String, LayoutManagerType> sDisplayNameLookup =
                new HashMap<String, LayoutManagerType>();

        static {
            for (LayoutManagerType type : LayoutManagerType.values()) {
                sDisplayNameLookup.put(type.mDisplayName, type);
            }
        }

        LayoutManagerType(String displayName, String className, Class[] signature, Object[] args) {
            mDisplayName = displayName;
            mClassName = className;
            mSignature = signature;
            mArgs = args;
        }

        String getClassName() {
            return mClassName;
        }

        Class[] getSignature() {
            return mSignature;
        }

        @NonNull
        Object[] getArgs(Context context) {
            Object[] args = new Object[mArgs.length];
            System.arraycopy(mArgs, 0, args, 0, mArgs.length);
            for (int i = 0; i < args.length; i++) {
                if (args[i] == CONTEXT) {
                    args[i] = context;
                }
            }
            return args;
        }

        @NonNull
        public static LayoutManagerType getDefault() {
            return LINEAR_LAYOUT_MANGER;
        }

        @Nullable
        public static LayoutManagerType getByDisplayName(@Nullable String className) {
            return sDisplayNameLookup.get(className);
        }
    }
}
