/*
 * Copyright (C) 2019 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.server.wm;

import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;

import android.annotation.Nullable;
import android.app.StatusBarManager;
import android.util.IntArray;
import android.view.InsetsState;
import android.view.InsetsState.InternalInsetsType;
import android.view.ViewRootImpl;

/**
 * Policy that implements who gets control over the windows generating insets.
 */
class InsetsPolicy {

    private final InsetsStateController mStateController;
    private final DisplayContent mDisplayContent;
    private final DisplayPolicy mPolicy;
    private final TransientControlTarget mTransientControlTarget = new TransientControlTarget();
    private final IntArray mShowingTransientTypes = new IntArray();

    private WindowState mFocusedWin;
    private BarWindow mStatusBar = new BarWindow(StatusBarManager.WINDOW_STATUS_BAR);
    private BarWindow mNavBar = new BarWindow(StatusBarManager.WINDOW_NAVIGATION_BAR);

    InsetsPolicy(InsetsStateController stateController, DisplayContent displayContent) {
        mStateController = stateController;
        mDisplayContent = displayContent;
        mPolicy = displayContent.getDisplayPolicy();
    }

    /** Updates the target which can control system bars. */
    void updateBarControlTarget(@Nullable WindowState focusedWin) {
        mFocusedWin = focusedWin;
        mStateController.onBarControlTargetChanged(getStatusControlTarget(focusedWin),
                getFakeStatusControlTarget(focusedWin),
                getNavControlTarget(focusedWin),
                getFakeNavControlTarget(focusedWin));
        if (ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL) {
            return;
        }
        mStatusBar.setVisible(focusedWin == null
                || focusedWin != getStatusControlTarget(focusedWin)
                || focusedWin.getRequestedInsetsState().getSource(ITYPE_STATUS_BAR).isVisible());
        mNavBar.setVisible(focusedWin == null
                || focusedWin != getNavControlTarget(focusedWin)
                || focusedWin.getRequestedInsetsState().getSource(ITYPE_NAVIGATION_BAR)
                        .isVisible());
    }

    boolean isHidden(@InternalInsetsType int type) {
        final InsetsSourceProvider provider =  mStateController.peekSourceProvider(type);
        return provider != null && provider.hasWindow() && !provider.getSource().isVisible();
    }

    void showTransient(IntArray types) {
        boolean changed = false;
        for (int i = types.size() - 1; i >= 0; i--) {
            final int type = types.get(i);
            if (mShowingTransientTypes.indexOf(type) != -1) {
                continue;
            }
            if (!isHidden(type)) {
                continue;
            }
            mShowingTransientTypes.add(type);
            changed = true;
        }
        if (changed) {
            updateBarControlTarget(mFocusedWin);
            mPolicy.getStatusBarManagerInternal().showTransient(mDisplayContent.getDisplayId(),
                    mShowingTransientTypes.toArray());
            mStateController.notifyInsetsChanged();
            // TODO(b/118118435): Animation
        }
    }

    void hideTransient() {
        if (mShowingTransientTypes.size() == 0) {
            return;
        }

        // TODO(b/118118435): Animation
        mShowingTransientTypes.clear();
        updateBarControlTarget(mFocusedWin);
        mStateController.notifyInsetsChanged();
    }

    boolean isTransient(@InternalInsetsType int type) {
        return mShowingTransientTypes.indexOf(type) != -1;
    }

    /**
     * @see InsetsStateController#getInsetsForDispatch
     */
    InsetsState getInsetsForDispatch(WindowState target) {
        InsetsState state = mStateController.getInsetsForDispatch(target);
        if (mShowingTransientTypes.size() == 0) {
            return state;
        }
        for (int i = mShowingTransientTypes.size() - 1; i >= 0; i--) {
            state.setSourceVisible(mShowingTransientTypes.get(i), false);
        }
        return state;
    }

    void onInsetsModified(WindowState windowState, InsetsState state) {
        mStateController.onInsetsModified(windowState, state);
        checkAbortTransient(windowState, state);
        if (ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL) {
            return;
        }
        if (windowState == getStatusControlTarget(mFocusedWin)) {
            mStatusBar.setVisible(state.getSource(ITYPE_STATUS_BAR).isVisible());
        }
        if (windowState == getNavControlTarget(mFocusedWin)) {
            mNavBar.setVisible(state.getSource(ITYPE_NAVIGATION_BAR).isVisible());
        }
    }

    /**
     * Called when a window modified the insets state. If the window set a insets source to visible
     * while it is shown transiently, we need to abort the transient state.
     *
     * @param windowState who changed the insets state.
     * @param state the modified insets state.
     */
    private void checkAbortTransient(WindowState windowState, InsetsState state) {
        if (mShowingTransientTypes.size() != 0) {
            IntArray abortTypes = new IntArray();
            for (int i = mShowingTransientTypes.size() - 1; i >= 0; i--) {
                final int type = mShowingTransientTypes.get(i);
                if (mStateController.isFakeTarget(type, windowState)
                        && state.getSource(type).isVisible()) {
                    mShowingTransientTypes.remove(i);
                    abortTypes.add(type);
                }
            }
            if (abortTypes.size() > 0) {
                mPolicy.getStatusBarManagerInternal().abortTransient(mDisplayContent.getDisplayId(),
                        abortTypes.toArray());
                updateBarControlTarget(mFocusedWin);
            }
        }
    }

    private @Nullable InsetsControlTarget getFakeStatusControlTarget(
            @Nullable WindowState focused) {
        if (mShowingTransientTypes.indexOf(ITYPE_STATUS_BAR) != -1) {
            return focused;
        }
        return null;
    }

    private @Nullable InsetsControlTarget getFakeNavControlTarget(@Nullable WindowState focused) {
        if (mShowingTransientTypes.indexOf(ITYPE_NAVIGATION_BAR) != -1) {
            return focused;
        }
        return null;
    }

    private @Nullable InsetsControlTarget getStatusControlTarget(@Nullable WindowState focusedWin) {
        if (mShowingTransientTypes.indexOf(ITYPE_STATUS_BAR) != -1) {
            return mTransientControlTarget;
        }
        if (areSystemBarsForciblyVisible() || isStatusBarForciblyVisible()) {
            return null;
        }
        return focusedWin;
    }

    private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin) {
        if (mShowingTransientTypes.indexOf(ITYPE_NAVIGATION_BAR) != -1) {
            return mTransientControlTarget;
        }
        if (areSystemBarsForciblyVisible() || isNavBarForciblyVisible()) {
            return null;
        }
        return focusedWin;
    }

    private boolean isStatusBarForciblyVisible() {
        final WindowState statusBar = mPolicy.getStatusBar();
        if (statusBar == null) {
            return false;
        }
        final int privateFlags = statusBar.mAttrs.privateFlags;

        // TODO(b/118118435): Pretend to the app that it's still able to control it?
        if ((privateFlags & PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT) != 0) {
            return true;
        }
        if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
            return true;
        }
        return false;
    }

    private boolean isNavBarForciblyVisible() {
        final WindowState statusBar = mPolicy.getStatusBar();
        if (statusBar == null) {
            return false;
        }
        if ((statusBar.mAttrs.privateFlags & PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION) != 0) {
            return true;
        }
        return false;
    }

    private boolean areSystemBarsForciblyVisible() {
        final boolean isDockedStackVisible =
                mDisplayContent.isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
        final boolean isFreeformStackVisible =
                mDisplayContent.isStackVisible(WINDOWING_MODE_FREEFORM);
        final boolean isResizing = mDisplayContent.getDockedDividerController().isResizing();

        // We need to force system bars when the docked stack is visible, when the freeform stack
        // is visible but also when we are resizing for the transitions when docked stack
        // visibility changes.
        return isDockedStackVisible || isFreeformStackVisible || isResizing;
    }

    private class BarWindow {

        private final int mId;
        private  @StatusBarManager.WindowVisibleState int mState =
                StatusBarManager.WINDOW_STATE_SHOWING;

        BarWindow(int id) {
            mId = id;
        }

        private void setVisible(boolean visible) {
            final int state = visible ? WINDOW_STATE_SHOWING : WINDOW_STATE_HIDDEN;
            if (mState != state) {
                mState = state;
                mPolicy.getStatusBarManagerInternal().setWindowState(
                        mDisplayContent.getDisplayId(), mId, state);
            }
        }
    }

    // TODO(b/118118435): Implement animations for it (with SurfaceAnimator)
    private class TransientControlTarget implements InsetsControlTarget {

        @Override
        public void notifyInsetsControlChanged() {
        }
    }
}
