/*
 * Copyright (C) 2018 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.systemui.util;

import android.content.Context;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;

import com.android.systemui.SystemUIFactory;
import com.android.systemui.qs.QSCarrierGroup;
import com.android.systemui.qs.QSFooterImpl;
import com.android.systemui.qs.QuickStatusBarHeader;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.phone.NotificationPanelView;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import dagger.Subcomponent;

/**
 * Manages inflation that requires dagger injection.
 * See docs/dagger.md for details.
 */
@Singleton
public class InjectionInflationController {

    public static final String VIEW_CONTEXT = "view_context";
    private final ViewCreator mViewCreator;
    private final ArrayMap<String, Method> mInjectionMap = new ArrayMap<>();
    private final LayoutInflater.Factory2 mFactory = new InjectionFactory();

    @Inject
    public InjectionInflationController(SystemUIFactory.SystemUIRootComponent rootComponent) {
        mViewCreator = rootComponent.createViewCreator();
        initInjectionMap();
    }

    ArrayMap<String, Method> getInjectionMap() {
        return mInjectionMap;
    }

    ViewCreator getFragmentCreator() {
        return mViewCreator;
    }

    /**
     * Wraps a {@link LayoutInflater} to support creating dagger injected views.
     * See docs/dagger.md for details.
     */
    public LayoutInflater injectable(LayoutInflater inflater) {
        LayoutInflater ret = inflater.cloneInContext(inflater.getContext());
        ret.setPrivateFactory(mFactory);
        return ret;
    }

    private void initInjectionMap() {
        for (Method method : ViewInstanceCreator.class.getDeclaredMethods()) {
            if (View.class.isAssignableFrom(method.getReturnType())
                    && (method.getModifiers() & Modifier.PUBLIC) != 0) {
                mInjectionMap.put(method.getReturnType().getName(), method);
            }
        }
    }

    /**
     * The subcomponent of dagger that holds all views that need injection.
     */
    @Subcomponent
    public interface ViewCreator {
        /**
         * Creates another subcomponent to actually generate the view.
         */
        ViewInstanceCreator createInstanceCreator(ViewAttributeProvider attributeProvider);
    }

    /**
     * Secondary sub-component that actually creates the views.
     *
     * Having two subcomponents lets us hide the complexity of providing the named context
     * and AttributeSet from the SystemUIRootComponent, instead we have one subcomponent that
     * creates a new ViewInstanceCreator any time we need to inflate a view.
     */
    @Subcomponent(modules = ViewAttributeProvider.class)
    public interface ViewInstanceCreator {
        /**
         * Creates the QuickStatusBarHeader.
         */
        QuickStatusBarHeader createQsHeader();
        /**
         * Creates the QSFooterImpl.
         */
        QSFooterImpl createQsFooter();

        /**
         * Creates the NotificationStackScrollLayout.
         */
        NotificationStackScrollLayout createNotificationStackScrollLayout();

        /**
         * Creates the NotificationPanelView.
         */
        NotificationPanelView createPanelView();

        /**
         * Creates the QSCarrierGroup
         */
        QSCarrierGroup createQSCarrierGroup();
    }

    /**
     * Module for providing view-specific constructor objects.
     */
    @Module
    public class ViewAttributeProvider {
        private final Context mContext;
        private final AttributeSet mAttrs;

        private ViewAttributeProvider(Context context, AttributeSet attrs) {
            mContext = context;
            mAttrs = attrs;
        }

        /**
         * Provides the view-themed context (as opposed to the global sysui application context).
         */
        @Provides
        @Named(VIEW_CONTEXT)
        public Context provideContext() {
            return mContext;
        }

        /**
         * Provides the AttributeSet for the current view being inflated.
         */
        @Provides
        public AttributeSet provideAttributeSet() {
            return mAttrs;
        }
    }

    private class InjectionFactory implements LayoutInflater.Factory2 {

        @Override
        public View onCreateView(String name, Context context, AttributeSet attrs) {
            Method creationMethod = mInjectionMap.get(name);
            if (creationMethod != null) {
                ViewAttributeProvider provider = new ViewAttributeProvider(context, attrs);
                try {
                    return (View) creationMethod.invoke(
                            mViewCreator.createInstanceCreator(provider));
                } catch (IllegalAccessException e) {
                    throw new InflateException("Could not inflate " + name, e);
                } catch (InvocationTargetException e) {
                    throw new InflateException("Could not inflate " + name, e);
                }
            }
            return null;
        }

        @Override
        public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
            return onCreateView(name, context, attrs);
        }
    }
}
