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

import android.os.SystemClock;
import android.util.LruCache;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;

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

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Cache of rotation and nudge history of rotary controller. With this cache, the users can reverse
 * course and go back where they were if they accidentally nudge too far.
 */
class RotaryCache {

    /** The cache is disabled. */
    @VisibleForTesting
    static final int CACHE_TYPE_DISABLED = 1;
    /** Entries in the cache will expire after a period of time. */
    @VisibleForTesting
    static final int CACHE_TYPE_EXPIRED_AFTER_SOME_TIME = 2;
    /** Entries in the cache will never expire as long as RotaryService is alive. */
    @VisibleForTesting
    static final int CACHE_TYPE_NEVER_EXPIRE = 3;

    @IntDef(flag = true, value = {
            CACHE_TYPE_DISABLED, CACHE_TYPE_EXPIRED_AFTER_SOME_TIME, CACHE_TYPE_NEVER_EXPIRE})
    @Retention(RetentionPolicy.SOURCE)
    public @interface CacheType {
    }

    @NonNull
    private NodeCopier mNodeCopier = new NodeCopier();

    /** Cache of last focused node by focus area. */
    @NonNull
    private final FocusHistoryCache mFocusHistoryCache;

    /** Cache of target focus area by source focus area and direction (up, down, left or right). */
    @NonNull
    private final FocusAreaHistoryCache mFocusAreaHistoryCache;

    /**
     * Cache of recently focused nodes in recently focused windows. Used to recover when the
     * focused window closes.
     */
    @NonNull
    private final FocusWindowCache mFocusWindowCache;

    /** A record of when a node was focused. */
    private static class FocusHistory {

        /**
         * A node representing a focusable {@link View} or a {@link com.android.car.ui.FocusArea}.
         */
        @NonNull
        final AccessibilityNodeInfo node;

        /** The {@link SystemClock#uptimeMillis} when this history was recorded. */
        final long timestamp;

        FocusHistory(@NonNull AccessibilityNodeInfo node, long timestamp) {
            this.node = node;
            this.timestamp = timestamp;
        }
    }

    /**
     * A combination of a source focus area and a direction (up, down, left or right). Used as a key
     * in {@link #mFocusAreaHistoryCache}.
     */
    private static class FocusAreaHistory {

        @NonNull
        final AccessibilityNodeInfo sourceFocusArea;
        final int direction;

        FocusAreaHistory(@NonNull AccessibilityNodeInfo sourceFocusArea, int direction) {
            this.sourceFocusArea = sourceFocusArea;
            this.direction = direction;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            FocusAreaHistory that = (FocusAreaHistory) o;
            return direction == that.direction
                    && Objects.equals(sourceFocusArea, that.sourceFocusArea);
        }

        @Override
        public int hashCode() {
            return Objects.hash(sourceFocusArea, direction);
        }
    }

    /** An entry in {@link #mFocusWindowCache}. */
    private static class FocusWindowHistory {
        /** A node in a window representing a focused {@link View}. */
        @NonNull
        final AccessibilityNodeInfo mNode;

        /** The {@link SystemClock#uptimeMillis} when this history was recorded. */
        final long mTimestamp;

        FocusWindowHistory(@NonNull AccessibilityNodeInfo node, long timestamp) {
            this.mNode = node;
            this.mTimestamp = timestamp;
        }

        void recycle() {
            this.mNode.recycle();
        }
    }

    /** A cache of the last focused node by focus area. */
    private class FocusHistoryCache extends LruCache<AccessibilityNodeInfo, FocusHistory> {

        /** Type of the cache. */
        private final @CacheType int mCacheType;

        /** How many milliseconds before an entry in the cache expires. */
        private final int mExpirationTimeMs;

        FocusHistoryCache(@CacheType int cacheType, int size, int expirationTimeMs) {
            super(size);
            mCacheType = cacheType;
            mExpirationTimeMs = expirationTimeMs;
            if (mCacheType == CACHE_TYPE_EXPIRED_AFTER_SOME_TIME && mExpirationTimeMs <= 0) {
                throw new IllegalArgumentException(
                        "Expiration time must be positive if CacheType is "
                                + "CACHE_TYPE_EXPIRED_AFTER_SOME_TIME");
            }
        }

        boolean enabled() {
            return mCacheType != CACHE_TYPE_DISABLED;
        }

        boolean isValidFocusHistory(@Nullable FocusHistory focusHistory, long elapsedRealtime) {
            if (focusHistory == null || focusHistory.node == null) {
                return false;
            }
            switch (mCacheType) {
                case CACHE_TYPE_NEVER_EXPIRE:
                    return true;
                case CACHE_TYPE_EXPIRED_AFTER_SOME_TIME:
                    return elapsedRealtime - focusHistory.timestamp < mExpirationTimeMs;
                default:
                    return false;
            }
        }

        @Override
        protected void entryRemoved(boolean evicted, AccessibilityNodeInfo key,
                FocusHistory oldValue, FocusHistory newValue) {
            Utils.recycleNode(key);
            Utils.recycleNode(oldValue.node);
        }
    }

    /**
     * A cache of the target focus area to nudge to, by source focus area and direction (up, down,
     * left or right).
     */
    private class FocusAreaHistoryCache extends LruCache<FocusAreaHistory, FocusHistory> {

        /** Type of the cache. */
        private final @CacheType int mCacheType;

        /** How many milliseconds before an entry in the cache expires. */
        private final int mExpirationTimeMs;

        FocusAreaHistoryCache(@CacheType int cacheType, int size, int expirationTimeMs) {
            super(size);
            mCacheType = cacheType;
            mExpirationTimeMs = expirationTimeMs;
            if (mCacheType == CACHE_TYPE_EXPIRED_AFTER_SOME_TIME && mExpirationTimeMs <= 0) {
                throw new IllegalArgumentException(
                        "Expiration time must be positive if CacheType is "
                                + "CACHE_TYPE_EXPIRED_AFTER_SOME_TIME");
            }
        }

        boolean enabled() {
            return mCacheType != CACHE_TYPE_DISABLED;
        }

        boolean isValidFocusHistory(@Nullable FocusHistory focusHistory, long elapsedRealtime) {
            if (focusHistory == null || focusHistory.node == null) {
                return false;
            }
            switch (mCacheType) {
                case CACHE_TYPE_NEVER_EXPIRE:
                    return true;
                case CACHE_TYPE_EXPIRED_AFTER_SOME_TIME:
                    return elapsedRealtime - focusHistory.timestamp < mExpirationTimeMs;
                default:
                    return false;
            }
        }

        @Override
        protected void entryRemoved(boolean evicted, FocusAreaHistory key, FocusHistory oldValue,
                FocusHistory newValue) {
            Utils.recycleNode(key.sourceFocusArea);
            Utils.recycleNode(oldValue.node);
        }
    }

    /**
     * A cache of recently focused nodes in recently focused windows. Used to recover when the
     * focused window closes.
     */
    private class FocusWindowCache extends LruCache<Integer, FocusWindowHistory> {
        @CacheType
        final int mCacheType;
        final int mExpirationTimeMs;

        FocusWindowCache(@CacheType int cacheType, int size, int expirationTimeMs) {
            super(size);
            mCacheType = cacheType;
            mExpirationTimeMs = expirationTimeMs;
            if (cacheType == CACHE_TYPE_EXPIRED_AFTER_SOME_TIME && expirationTimeMs <= 0) {
                throw new IllegalArgumentException(
                        "Expiration time must be positive if CacheType is "
                                + "CACHE_TYPE_EXPIRED_AFTER_SOME_TIME");
            }
        }

        /**
         * Returns whether an entry in this cache is valid. To be valid:
         * <ul>
         *     <li>the cached node must still be in the view tree
         *     <li>the cached node must still be able to take focus
         *     <li>the cache entry must not have expired
         * </ul>
         */
        boolean isValidEntry(@NonNull FocusWindowHistory focusWindowHistory, long elapsedRealtime) {
            if (!focusWindowHistory.mNode.refresh()
                    || !Utils.canTakeFocus(focusWindowHistory.mNode)) {
                return false;
            }

            switch (mCacheType) {
                case CACHE_TYPE_NEVER_EXPIRE:
                    return true;
                case CACHE_TYPE_EXPIRED_AFTER_SOME_TIME:
                    return elapsedRealtime - focusWindowHistory.mTimestamp < mExpirationTimeMs;
                default:
                    return false;
            }
        }

        /**
         * Stores the given (window ID, node) pair, overwriting the existing pair with the given
         * window ID, if any.
         */
        void put(int windowId, @NonNull AccessibilityNodeInfo node, long elapsedRealtime) {
            if (mCacheType == CACHE_TYPE_DISABLED) {
                return;
            }
            put(windowId, new FocusWindowHistory(copyNode(node), elapsedRealtime));
        }

        /**
         * Returns the most recently focused valid node in window {@code windowId}, or {@code null}
         * if there are no valid nodes in the cache. The caller is responsible for recycling the
         * result.
         */
        @Nullable
        AccessibilityNodeInfo getMostRecentValidNode(int windowId, long elapsedRealtime) {
            FocusWindowHistory focusWindowHistory = get(windowId);
            if (focusWindowHistory != null && isValidEntry(focusWindowHistory, elapsedRealtime)) {
                return copyNode(focusWindowHistory.mNode);
            }
            return null;
        }

        @Override
        protected void entryRemoved(boolean evicted, Integer windowId, FocusWindowHistory oldValue,
                FocusWindowHistory newValue) {
            oldValue.recycle();
        }
    }

    RotaryCache(@CacheType int focusHistoryCacheType,
            int focusHistoryCacheSize,
            int focusHistoryExpirationTimeMs,
            @CacheType int focusAreaHistoryCacheType,
            int focusAreaHistoryCacheSize,
            int focusAreaHistoryExpirationTimeMs,
            @CacheType int focusWindowCacheType,
            int focusWindowCacheSize,
            int focusWindowExpirationTimeMs) {
        mFocusHistoryCache = new FocusHistoryCache(
                focusHistoryCacheType, focusHistoryCacheSize, focusHistoryExpirationTimeMs);
        mFocusAreaHistoryCache = new FocusAreaHistoryCache(focusAreaHistoryCacheType,
                focusAreaHistoryCacheSize, focusAreaHistoryExpirationTimeMs);
        mFocusWindowCache = new FocusWindowCache(focusWindowCacheType, focusWindowCacheSize,
                focusWindowExpirationTimeMs);
    }

    /**
     * Searches the cache to find the last focused node in the given {@code focusArea}. Returns the
     * node, or null if there is nothing in the cache, the cache is stale, the view represented
     * by the node is no longer in the view tree, or the node's state has changed so that it can't
     * take focus any more. The caller is responsible for recycling the result.
     */
    AccessibilityNodeInfo getFocusedNode(@NonNull AccessibilityNodeInfo focusArea,
            long elapsedRealtime) {
        if (mFocusHistoryCache.enabled()) {
            FocusHistory focusHistory = mFocusHistoryCache.get(focusArea);
            if (mFocusHistoryCache.isValidFocusHistory(focusHistory, elapsedRealtime)) {
                AccessibilityNodeInfo node = copyNode(focusHistory.node);
                // Refresh the node in case the view represented by the node is no longer in the
                // view tree, or the node's state (e.g., isFocused()) has changed.
                AccessibilityNodeInfo refreshedNode = Utils.refreshNode(node);

                // If the node's state has changed so that it can't take focus any more, return
                // null.
                if (refreshedNode != null && !Utils.canTakeFocus(refreshedNode)) {
                    Utils.recycleNode(refreshedNode);
                    refreshedNode = null;
                }
                return refreshedNode;
            }
        }
        return null;
    }

    /**
     * Caches the last focused node by focus area. A copy of {@code focusArea} and {@code
     * focusedNode} will be saved in the cache.
     */
    void saveFocusedNode(@NonNull AccessibilityNodeInfo focusArea,
            @NonNull AccessibilityNodeInfo focusedNode, long elapsedRealtime) {
        if (mFocusHistoryCache.enabled()) {
            mFocusHistoryCache.put(
                    copyNode(focusArea), new FocusHistory(copyNode(focusedNode), elapsedRealtime));
        }
    }

    /**
     * Searches the cache to find the target focus area for a nudge in a given {@code direction}
     * from a given focus area. Returns the focus area, or null if there is nothing in the cache,
     * the cache is stale, or the view represented by the node is no longer in the view tree.
     * The caller is responsible for recycling the result.
     */
    AccessibilityNodeInfo getTargetFocusArea(@NonNull AccessibilityNodeInfo sourceFocusArea,
            int direction, long elapsedRealtime) {
        if (mFocusAreaHistoryCache.enabled()) {
            FocusHistory focusHistory =
                    mFocusAreaHistoryCache.get(new FocusAreaHistory(sourceFocusArea, direction));
            if (mFocusAreaHistoryCache.isValidFocusHistory(focusHistory, elapsedRealtime)) {
                AccessibilityNodeInfo focusArea = copyNode(focusHistory.node);
                // Refresh the node in case the view represented by the node is no longer in the
                // view tree.
                return Utils.refreshNode(focusArea);
            }
        }
        return null;
    }

    /**
     * Caches the focus area nudge history. A copy of {@code sourceFocusArea} and {@code
     * targetFocusArea} will be saved in the cache.
     */
    void saveTargetFocusArea(@NonNull AccessibilityNodeInfo sourceFocusArea,
            @NonNull AccessibilityNodeInfo targetFocusArea, int direction, long elapsedRealtime) {
        if (mFocusAreaHistoryCache.enabled()) {
            int oppositeDirection = getOppositeDirection(direction);
            mFocusAreaHistoryCache
                    .put(new FocusAreaHistory(copyNode(targetFocusArea), oppositeDirection),
                            new FocusHistory(copyNode(sourceFocusArea), elapsedRealtime));
        }
    }

    /** Clears the focus area nudge history cache. */
    void clearFocusAreaHistory() {
        if (mFocusAreaHistoryCache.enabled()) {
            mFocusAreaHistoryCache.evictAll();
        }
    }

    @VisibleForTesting
    boolean isFocusAreaHistoryCacheEmpty() {
        return mFocusAreaHistoryCache.size() == 0;
    }

    /** Saves the most recently focused node within a window. */
    void saveWindowFocus(@NonNull AccessibilityNodeInfo focusedNode, long elapsedRealtime) {
        mFocusWindowCache.put(focusedNode.getWindowId(), focusedNode, elapsedRealtime);
    }

    /**
     * Returns the most recently focused valid node in window {@code windowId}, or {@code null} if
     * there are no valid nodes saved by {@link #saveWindowFocus}. The caller is responsible for
     * recycling the result.
     */
    @Nullable
    AccessibilityNodeInfo getMostRecentFocus(int windowId, long elapsedRealtime) {
        return mFocusWindowCache.getMostRecentValidNode(windowId, elapsedRealtime);
    }

    /** Returns the direction opposite the given {@code direction} */
    @VisibleForTesting
    static int getOppositeDirection(int direction) {
        switch (direction) {
            case View.FOCUS_LEFT:
                return View.FOCUS_RIGHT;
            case View.FOCUS_RIGHT:
                return View.FOCUS_LEFT;
            case View.FOCUS_UP:
                return View.FOCUS_DOWN;
            case View.FOCUS_DOWN:
                return View.FOCUS_UP;
        }
        throw new IllegalArgumentException("direction must be "
                + "FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, or FOCUS_RIGHT.");
    }

    /** Sets a mock {@link NodeCopier} instance for testing. */
    @VisibleForTesting
    void setNodeCopier(@NonNull NodeCopier nodeCopier) {
        mNodeCopier = nodeCopier;
    }

    private AccessibilityNodeInfo copyNode(@Nullable AccessibilityNodeInfo node) {
        return mNodeCopier.copy(node);
    }
}
