/*
 * Copyright (C) 2020 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.car.systembar;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;

import android.app.ActivityTaskManager;
import android.app.ActivityTaskManager.RootTaskInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import com.android.systemui.dagger.SysUISingleton;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.inject.Inject;

/**
 * CarSystemBarButtons can optionally have selection state that toggles certain visual indications
 * based on whether the active application on screen is associated with it. This is basically a
 * similar concept to a radio button group.
 *
 * This class controls the selection state of CarSystemBarButtons that have opted in to have such
 * selection state-dependent visual indications.
 */
@SysUISingleton
public class ButtonSelectionStateController {
    private static final String TAG = ButtonSelectionStateController.class.getSimpleName();

    private final Set<CarSystemBarButton> mRegisteredViews = new HashSet<>();

    protected ButtonMap mButtonsByCategory = new ButtonMap();
    protected ButtonMap mButtonsByPackage = new ButtonMap();
    protected ButtonMap mButtonsByComponentName = new ButtonMap();
    protected HashSet<CarSystemBarButton> mSelectedButtons;
    protected Context mContext;

    @Inject
    public ButtonSelectionStateController(Context context) {
        mContext = context;
        mSelectedButtons = new HashSet<>();
    }

    /**
     * Iterate through a view looking for CarSystemBarButton and add it to the controller if it
     * opted in to be highlighted when the active application is associated with it.
     *
     * @param v the View that may contain CarFacetButtons
     */
    protected void addAllButtonsWithSelectionState(View v) {
        if (v instanceof CarSystemBarButton) {
            if (((CarSystemBarButton) v).hasSelectionState()) {
                addButtonWithSelectionState((CarSystemBarButton) v);
            }
        } else if (v instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup) v;
            for (int i = 0; i < viewGroup.getChildCount(); i++) {
                addAllButtonsWithSelectionState(viewGroup.getChildAt(i));
            }
        }
    }

    /** Removes all buttons from the button maps. */
    protected void removeAll() {
        mButtonsByCategory.clear();
        mButtonsByPackage.clear();
        mButtonsByComponentName.clear();
        mSelectedButtons.clear();
        mRegisteredViews.clear();
    }

    /**
     * This will unselect the currently selected CarSystemBarButton and determine which one should
     * be selected next. It does this by reading the properties on the CarSystemBarButton and
     * seeing if they are a match with the supplied StackInfo list.
     * The order of selection detection is ComponentName, PackageName then Category
     * They will then be compared with the supplied StackInfo list.
     * The StackInfo is expected to be supplied in order of recency and StackInfo will only be used
     * for consideration if it has the same displayId as the CarSystemBarButton.
     *
     * @param taskInfoList of the currently running application
     * @param validDisplay index of the valid display
     */

    protected void taskChanged(List<RootTaskInfo> taskInfoList, int validDisplay) {
        RootTaskInfo validTaskInfo = null;
        for (RootTaskInfo taskInfo : taskInfoList) {
            // Find the first stack info with a topActivity in the primary display.
            // TODO: We assume that CarFacetButton will launch an app only in the primary display.
            // We need to extend the functionality to handle the multiple display properly.
            if (taskInfo.topActivity != null && taskInfo.displayAreaFeatureId == validDisplay) {
                validTaskInfo = taskInfo;
                break;
            }
        }

        if (validTaskInfo == null) {
            // No stack was found that was on the same display as the buttons thus return
            return;
        }
        int displayId = validTaskInfo.displayId;

        // Clear all registered views
        mRegisteredViews.forEach(carSystemBarButton -> {
            if (carSystemBarButton.getDisplayId() == displayId) {
                carSystemBarButton.setSelected(false);
            }
        });
        mSelectedButtons.clear();

        HashSet<CarSystemBarButton> selectedButtons = findSelectedButtons(validTaskInfo);

        if (selectedButtons != null) {
            selectedButtons.forEach(carSystemBarButton -> {
                if (carSystemBarButton.getDisplayId() == displayId) {
                    carSystemBarButton.setSelected(true);
                    mSelectedButtons.add(carSystemBarButton);
                }
            });
        }
    }

    /**
     * Defaults to Display.DEFAULT_DISPLAY when no parameter is provided for the validDisplay.
     *
     * @param taskInfoList
     */
    protected void taskChanged(List<RootTaskInfo> taskInfoList) {
        taskChanged(taskInfoList, FEATURE_DEFAULT_TASK_CONTAINER);
    }

    /**
     * Add navigation button to this controller if it uses selection state.
     */
    private void addButtonWithSelectionState(CarSystemBarButton carSystemBarButton) {
        if (mRegisteredViews.contains(carSystemBarButton)) {
            return;
        }
        String[] categories = carSystemBarButton.getCategories();
        for (int i = 0; i < categories.length; i++) {
            mButtonsByCategory.add(categories[i], carSystemBarButton);
        }

        String[] packages = carSystemBarButton.getPackages();
        for (int i = 0; i < packages.length; i++) {
            mButtonsByPackage.add(packages[i], carSystemBarButton);
        }
        String[] componentNames = carSystemBarButton.getComponentName();
        for (int i = 0; i < componentNames.length; i++) {
            mButtonsByComponentName.add(componentNames[i], carSystemBarButton);
        }

        mRegisteredViews.add(carSystemBarButton);
    }

    private HashSet<CarSystemBarButton> findSelectedButtons(RootTaskInfo validTaskInfo) {
        ComponentName topActivity = null;

        // Window mode being WINDOW_MODE_MULTI_WINDOW implies TaskView might be visible on the
        // display. In such cases, topActivity reported by validTaskInfo will be the one hosted in
        // TaskView and not necessarily the main activity visible on display. Thus we should get
        // rootTaskInfo instead.
        if (validTaskInfo.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW) {
            try {
                RootTaskInfo rootTaskInfo =
                        ActivityTaskManager.getService().getRootTaskInfoOnDisplay(
                                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_UNDEFINED,
                                validTaskInfo.displayId);
                topActivity = rootTaskInfo.topActivity;
            } catch (RemoteException e) {
                Log.e(TAG, "findSelectedButtons: Failed getting root task info", e);
            }
        } else {
            topActivity = validTaskInfo.topActivity;
        }

        if (topActivity == null) return null;

        String packageName = topActivity.getPackageName();

        HashSet<CarSystemBarButton> selectedButtons =
                findButtonsByComponentName(topActivity);
        if (selectedButtons == null) {
            selectedButtons = mButtonsByPackage.get(packageName);
        }
        if (selectedButtons == null) {
            String category = getPackageCategory(packageName);
            if (category != null) {
                selectedButtons = mButtonsByCategory.get(category);
            }
        }

        return selectedButtons;
    }

    private HashSet<CarSystemBarButton> findButtonsByComponentName(
            ComponentName componentName) {
        HashSet<CarSystemBarButton> buttons =
                mButtonsByComponentName.get(componentName.flattenToShortString());
        return (buttons != null) ? buttons :
                mButtonsByComponentName.get(componentName.flattenToString());
    }

    private String getPackageCategory(String packageName) {
        PackageManager pm = mContext.getPackageManager();
        Set<String> supportedCategories = mButtonsByCategory.keySet();
        for (String category : supportedCategories) {
            Intent intent = new Intent();
            intent.setPackage(packageName);
            intent.setAction(Intent.ACTION_MAIN);
            intent.addCategory(category);
            List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
            if (list.size() > 0) {
                // Cache this package name into ButtonsByPackage map, so we won't have to query
                // all categories next time this package name shows up.
                mButtonsByPackage.put(packageName, mButtonsByCategory.get(category));
                return category;
            }
        }
        return null;
    }

    // simple multi-map
    private static class ButtonMap extends HashMap<String, HashSet<CarSystemBarButton>> {

        public boolean add(String key, CarSystemBarButton value) {
            if (containsKey(key)) {
                return get(key).add(value);
            }
            HashSet<CarSystemBarButton> set = new HashSet<>();
            set.add(value);
            put(key, set);
            return true;
        }
    }
}
