/*
 * 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.wm.shell.pip;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;

import android.annotation.Nullable;
import android.app.ActivityTaskManager;
import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.RemoteAction;
import android.content.ComponentName;
import android.content.Context;
import android.os.RemoteException;
import android.util.Log;
import android.util.Pair;
import android.window.TaskSnapshot;

import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.protolog.ShellProtoLogGroup;

import java.util.List;
import java.util.Objects;

/** A class that includes convenience methods. */
public class PipUtils {
    private static final String TAG = "PipUtils";

    // Minimum difference between two floats (e.g. aspect ratios) to consider them not equal.
    private static final double EPSILON = 1e-7;

    /**
     * @return the ComponentName and user id of the top non-SystemUI activity in the pinned stack.
     * The component name may be null if no such activity exists.
     */
    public static Pair<ComponentName, Integer> getTopPipActivity(Context context) {
        try {
            final String sysUiPackageName = context.getPackageName();
            final RootTaskInfo pinnedTaskInfo = ActivityTaskManager.getService().getRootTaskInfo(
                    WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
            if (pinnedTaskInfo != null && pinnedTaskInfo.childTaskIds != null
                    && pinnedTaskInfo.childTaskIds.length > 0) {
                for (int i = pinnedTaskInfo.childTaskNames.length - 1; i >= 0; i--) {
                    ComponentName cn = ComponentName.unflattenFromString(
                            pinnedTaskInfo.childTaskNames[i]);
                    if (cn != null && !cn.getPackageName().equals(sysUiPackageName)) {
                        return new Pair<>(cn, pinnedTaskInfo.childTaskUserIds[i]);
                    }
                }
            }
        } catch (RemoteException e) {
            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: Unable to get pinned stack.", TAG);
        }
        return new Pair<>(null, 0);
    }

    /**
     * @return true if the aspect ratios differ
     */
    public static boolean aspectRatioChanged(float aspectRatio1, float aspectRatio2) {
        return Math.abs(aspectRatio1 - aspectRatio2) > EPSILON;
    }

    /**
     * Checks whether title, description and intent match.
     * Comparing icons would be good, but using equals causes false negatives
     */
    public static boolean remoteActionsMatch(RemoteAction action1, RemoteAction action2) {
        if (action1 == action2) return true;
        if (action1 == null || action2 == null) return false;
        return Objects.equals(action1.getTitle(), action2.getTitle())
                && Objects.equals(action1.getContentDescription(), action2.getContentDescription())
                && Objects.equals(action1.getActionIntent(), action2.getActionIntent());
    }

    /**
     * Returns true if the actions in the lists match each other according to {@link
     * PipUtils#remoteActionsMatch(RemoteAction, RemoteAction)}, including their position.
     */
    public static boolean remoteActionsChanged(List<RemoteAction> list1, List<RemoteAction> list2) {
        if (list1 == null && list2 == null) {
            return false;
        }
        if (list1 == null || list2 == null) {
            return true;
        }
        if (list1.size() != list2.size()) {
            return true;
        }
        for (int i = 0; i < list1.size(); i++) {
            if (!remoteActionsMatch(list1.get(i), list2.get(i))) {
                return true;
            }
        }
        return false;
    }

    /** @return {@link TaskSnapshot} for a given task id. */
    @Nullable
    public static TaskSnapshot getTaskSnapshot(int taskId, boolean isLowResolution) {
        if (taskId <= 0) return null;
        try {
            return ActivityTaskManager.getService().getTaskSnapshot(
                    taskId, isLowResolution, false /* takeSnapshotIfNeeded */);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to get task snapshot, taskId=" + taskId, e);
            return null;
        }
    }
}
