/*
 * 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.onehanded;

import static com.android.internal.jank.InteractionJankMonitor.CUJ_ONE_HANDED_ENTER_TRANSITION;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_ONE_HANDED_EXIT_TRANSITION;
import static com.android.wm.shell.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_EXIT;
import static com.android.wm.shell.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_TRIGGER;

import android.content.Context;
import android.graphics.Rect;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.view.SurfaceControl;
import android.window.DisplayAreaAppearedInfo;
import android.window.DisplayAreaInfo;
import android.window.DisplayAreaOrganizer;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import com.android.internal.jank.InteractionJankMonitor;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Manages OneHanded display areas such as offset.
 *
 * This class listens on {@link DisplayAreaOrganizer} callbacks for windowing mode change
 * both to and from OneHanded and issues corresponding animation if applicable.
 * Normally, we apply series of {@link SurfaceControl.Transaction} when the animator is running
 * and files a final {@link WindowContainerTransaction} at the end of the transition.
 *
 * This class is also responsible for translating one handed operations within SysUI component
 */
public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
    private static final String TAG = "OneHandedDisplayAreaOrganizer";
    private static final String ONE_HANDED_MODE_TRANSLATE_ANIMATION_DURATION =
            "persist.debug.one_handed_translate_animation_duration";

    private DisplayLayout mDisplayLayout = new DisplayLayout();

    private final Rect mLastVisualDisplayBounds = new Rect();
    private final Rect mDefaultDisplayBounds = new Rect();
    private final OneHandedSettingsUtil mOneHandedSettingsUtil;
    private final InteractionJankMonitor mJankMonitor;
    private final Context mContext;

    private boolean mIsReady;
    private float mLastVisualOffset = 0;
    private int mEnterExitAnimationDurationMs;

    private ArrayMap<WindowContainerToken, SurfaceControl> mDisplayAreaTokenMap = new ArrayMap();
    private OneHandedAnimationController mAnimationController;
    private OneHandedSurfaceTransactionHelper.SurfaceControlTransactionFactory
            mSurfaceControlTransactionFactory;
    private OneHandedTutorialHandler mTutorialHandler;
    private List<OneHandedTransitionCallback> mTransitionCallbacks = new ArrayList<>();

    @VisibleForTesting
    OneHandedAnimationCallback mOneHandedAnimationCallback =
            new OneHandedAnimationCallback() {
                @Override
                public void onOneHandedAnimationStart(
                        OneHandedAnimationController.OneHandedTransitionAnimator animator) {
                    final boolean isEntering = animator.getTransitionDirection()
                            == TRANSITION_DIRECTION_TRIGGER;
                    if (!mTransitionCallbacks.isEmpty()) {
                        for (int i = mTransitionCallbacks.size() - 1; i >= 0; i--) {
                            final OneHandedTransitionCallback cb = mTransitionCallbacks.get(i);
                            cb.onStartTransition(isEntering);
                        }
                    }
                }

                @Override
                public void onOneHandedAnimationEnd(SurfaceControl.Transaction tx,
                        OneHandedAnimationController.OneHandedTransitionAnimator animator) {
                    mAnimationController.removeAnimator(animator.getToken());
                    final boolean isEntering = animator.getTransitionDirection()
                            == TRANSITION_DIRECTION_TRIGGER;
                    if (mAnimationController.isAnimatorsConsumed()) {
                        endCUJTracing(isEntering ? CUJ_ONE_HANDED_ENTER_TRANSITION
                                : CUJ_ONE_HANDED_EXIT_TRANSITION);
                        finishOffset((int) animator.getDestinationOffset(),
                                animator.getTransitionDirection());
                    }
                }

                @Override
                public void onOneHandedAnimationCancel(
                        OneHandedAnimationController.OneHandedTransitionAnimator animator) {
                    mAnimationController.removeAnimator(animator.getToken());
                    final boolean isEntering = animator.getTransitionDirection()
                            == TRANSITION_DIRECTION_TRIGGER;
                    if (mAnimationController.isAnimatorsConsumed()) {
                        cancelCUJTracing(isEntering ? CUJ_ONE_HANDED_ENTER_TRANSITION
                                : CUJ_ONE_HANDED_EXIT_TRANSITION);
                        finishOffset((int) animator.getDestinationOffset(),
                                animator.getTransitionDirection());
                    }
                }
            };

    /**
     * Constructor of OneHandedDisplayAreaOrganizer
     */
    public OneHandedDisplayAreaOrganizer(Context context,
            DisplayLayout displayLayout,
            OneHandedSettingsUtil oneHandedSettingsUtil,
            OneHandedAnimationController animationController,
            OneHandedTutorialHandler tutorialHandler,
            InteractionJankMonitor jankMonitor,
            ShellExecutor mainExecutor) {
        super(mainExecutor);
        mContext = context;
        setDisplayLayout(displayLayout);
        mOneHandedSettingsUtil = oneHandedSettingsUtil;
        mAnimationController = animationController;
        mJankMonitor = jankMonitor;
        final int animationDurationConfig = context.getResources().getInteger(
                R.integer.config_one_handed_translate_animation_duration);
        mEnterExitAnimationDurationMs =
                SystemProperties.getInt(ONE_HANDED_MODE_TRANSLATE_ANIMATION_DURATION,
                        animationDurationConfig);
        mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
        mTutorialHandler = tutorialHandler;
    }

    @Override
    public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo,
            @NonNull SurfaceControl leash) {
        mDisplayAreaTokenMap.put(displayAreaInfo.token, leash);
    }

    @Override
    public void onDisplayAreaVanished(@NonNull DisplayAreaInfo displayAreaInfo) {
        final SurfaceControl leash = mDisplayAreaTokenMap.get(displayAreaInfo.token);
        if (leash != null) {
            leash.release();
        }
        mDisplayAreaTokenMap.remove(displayAreaInfo.token);
    }

    @Override
    public List<DisplayAreaAppearedInfo> registerOrganizer(int displayAreaFeature) {
        final List<DisplayAreaAppearedInfo> displayAreaInfos =
                super.registerOrganizer(displayAreaFeature);
        for (int i = 0; i < displayAreaInfos.size(); i++) {
            final DisplayAreaAppearedInfo info = displayAreaInfos.get(i);
            onDisplayAreaAppeared(info.getDisplayAreaInfo(), info.getLeash());
        }
        mIsReady = true;
        updateDisplayBounds();
        return displayAreaInfos;
    }

    @Override
    public void unregisterOrganizer() {
        super.unregisterOrganizer();
        mIsReady = false;
        resetWindowsOffset();
    }

    boolean isReady() {
        return mIsReady;
    }

    /**
     * Handler for display rotation changes by {@link DisplayLayout}
     *
     * @param context    Any context
     * @param toRotation target rotation of the display (after rotating).
     * @param wct        A task transaction {@link WindowContainerTransaction} from
     *                   {@link DisplayChangeController} to populate.
     */
    public void onRotateDisplay(Context context, int toRotation, WindowContainerTransaction wct) {
        if (mDisplayLayout.rotation() == toRotation) {
            return;
        }
        mDisplayLayout.rotateTo(context.getResources(), toRotation);
        updateDisplayBounds();
        finishOffset(0, TRANSITION_DIRECTION_EXIT);
    }

    /**
     * Offset the windows by a given offset on Y-axis, triggered also from screen rotation.
     * Directly perform manipulation/offset on the leash.
     */
    public void scheduleOffset(int xOffset, int yOffset) {
        final float fromPos = mLastVisualOffset;
        final int direction = yOffset > 0
                ? TRANSITION_DIRECTION_TRIGGER
                : TRANSITION_DIRECTION_EXIT;
        if (direction == TRANSITION_DIRECTION_TRIGGER) {
            beginCUJTracing(CUJ_ONE_HANDED_ENTER_TRANSITION, "enterOneHanded");
        } else {
            beginCUJTracing(CUJ_ONE_HANDED_EXIT_TRANSITION, "stopOneHanded");
        }
        mDisplayAreaTokenMap.forEach(
                (token, leash) -> {
                    animateWindows(token, leash, fromPos, yOffset, direction,
                            mEnterExitAnimationDurationMs);
                });
        mLastVisualOffset = yOffset;
    }

    @VisibleForTesting
    void resetWindowsOffset() {
        final SurfaceControl.Transaction tx =
                mSurfaceControlTransactionFactory.getTransaction();
        mDisplayAreaTokenMap.forEach(
                (token, leash) -> {
                    final OneHandedAnimationController.OneHandedTransitionAnimator animator =
                            mAnimationController.getAnimatorMap().remove(token);
                    if (animator != null && animator.isRunning()) {
                        animator.cancel();
                    }
                    tx.setPosition(leash, 0, 0)
                            .setWindowCrop(leash, -1, -1)
                            .setCornerRadius(leash, -1);
                });
        tx.apply();
        mLastVisualOffset = 0;
        mLastVisualDisplayBounds.offsetTo(0, 0);
    }

    private void animateWindows(WindowContainerToken token, SurfaceControl leash, float fromPos,
            float toPos, @OneHandedAnimationController.TransitionDirection int direction,
            int durationMs) {
        final OneHandedAnimationController.OneHandedTransitionAnimator animator =
                mAnimationController.getAnimator(token, leash, fromPos, toPos,
                        mLastVisualDisplayBounds);
        if (animator != null) {
            animator.setTransitionDirection(direction)
                    .addOneHandedAnimationCallback(mOneHandedAnimationCallback)
                    .addOneHandedAnimationCallback(mTutorialHandler)
                    .setDuration(durationMs)
                    .start();
        }
    }

    @VisibleForTesting
    void finishOffset(int offset, @OneHandedAnimationController.TransitionDirection int direction) {
        if (direction == TRANSITION_DIRECTION_EXIT) {
            // We must do this to ensure reset property for leash when exit one handed mode
            resetWindowsOffset();
        }
        mLastVisualOffset = direction == TRANSITION_DIRECTION_TRIGGER ? offset : 0;
        mLastVisualDisplayBounds.offsetTo(0, Math.round(mLastVisualOffset));
        for (int i = mTransitionCallbacks.size() - 1; i >= 0; i--) {
            final OneHandedTransitionCallback cb = mTransitionCallbacks.get(i);
            if (direction == TRANSITION_DIRECTION_TRIGGER) {
                cb.onStartFinished(getLastVisualDisplayBounds());
            } else {
                cb.onStopFinished(getLastVisualDisplayBounds());
            }
        }
    }

    /**
     * The latest visual bounds of displayArea translated
     *
     * @return Rect latest finish_offset
     */
    private Rect getLastVisualDisplayBounds() {
        return mLastVisualDisplayBounds;
    }

    @VisibleForTesting
    @Nullable
    Rect getLastDisplayBounds() {
        return mLastVisualDisplayBounds;
    }

    public DisplayLayout getDisplayLayout() {
        return mDisplayLayout;
    }

    @VisibleForTesting
    void setDisplayLayout(@NonNull DisplayLayout displayLayout) {
        mDisplayLayout.set(displayLayout);
        updateDisplayBounds();
    }

    @VisibleForTesting
    ArrayMap<WindowContainerToken, SurfaceControl> getDisplayAreaTokenMap() {
        return mDisplayAreaTokenMap;
    }

    @VisibleForTesting
    void updateDisplayBounds() {
        mDefaultDisplayBounds.set(0, 0, mDisplayLayout.width(), mDisplayLayout.height());
        mLastVisualDisplayBounds.set(mDefaultDisplayBounds);
    }

    /**
     * Register transition callback
     */
    public void registerTransitionCallback(OneHandedTransitionCallback callback) {
        mTransitionCallbacks.add(callback);
    }

    void beginCUJTracing(@InteractionJankMonitor.CujType int cujType, @Nullable String tag) {
        final Map.Entry<WindowContainerToken, SurfaceControl> firstEntry =
                getDisplayAreaTokenMap().entrySet().iterator().next();
        final InteractionJankMonitor.Configuration.Builder builder =
                InteractionJankMonitor.Configuration.Builder.withSurface(
                        cujType, mContext, firstEntry.getValue());
        if (!TextUtils.isEmpty(tag)) {
            builder.setTag(tag);
        }
        mJankMonitor.begin(builder);
    }

    void endCUJTracing(@InteractionJankMonitor.CujType int cujType) {
        mJankMonitor.end(cujType);
    }

    void cancelCUJTracing(@InteractionJankMonitor.CujType int cujType) {
        mJankMonitor.cancel(cujType);
    }

    void dump(@NonNull PrintWriter pw) {
        final String innerPrefix = "  ";
        pw.println(TAG);
        pw.print(innerPrefix + "mDisplayLayout.rotation()=");
        pw.println(mDisplayLayout.rotation());
        pw.print(innerPrefix + "mDisplayAreaTokenMap=");
        pw.println(mDisplayAreaTokenMap);
        pw.print(innerPrefix + "mDefaultDisplayBounds=");
        pw.println(mDefaultDisplayBounds);
        pw.print(innerPrefix + "mIsReady=");
        pw.println(mIsReady);
        pw.print(innerPrefix + "mLastVisualDisplayBounds=");
        pw.println(mLastVisualDisplayBounds);
        pw.print(innerPrefix + "mLastVisualOffset=");
        pw.println(mLastVisualOffset);

        if (mAnimationController != null) {
            mAnimationController.dump(pw);
        }
    }
}
