/*
 * Copyright (C) 2021 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.
 */
#include <optional>
#define LOG_TAG "InputDispatcher"
#define ATRACE_TAG ATRACE_TAG_INPUT

#define INDENT "  "
#define INDENT2 "    "

#include <inttypes.h>

#include <android-base/stringprintf.h>
#include <binder/Binder.h>
#include <ftl/enum.h>
#include <gui/WindowInfo.h>
#include <unordered_set>

#include "DebugConfig.h"
#include "FocusResolver.h"

using android::gui::FocusRequest;
using android::gui::WindowInfoHandle;

namespace android::inputdispatcher {

template <typename T>
struct SpHash {
    size_t operator()(const sp<T>& k) const { return std::hash<T*>()(k.get()); }
};

sp<IBinder> FocusResolver::getFocusedWindowToken(int32_t displayId) const {
    auto it = mFocusedWindowTokenByDisplay.find(displayId);
    return it != mFocusedWindowTokenByDisplay.end() ? it->second.second : nullptr;
}

std::optional<FocusRequest> FocusResolver::getFocusRequest(int32_t displayId) {
    auto it = mFocusRequestByDisplay.find(displayId);
    return it != mFocusRequestByDisplay.end() ? std::make_optional<>(it->second) : std::nullopt;
}

/**
 * 'setInputWindows' is called when the window properties change. Here we will check whether the
 * currently focused window can remain focused. If the currently focused window remains eligible
 * for focus ('isTokenFocusable' returns OK), then we will continue to grant it focus otherwise
 * we will check if the previous focus request is eligible to receive focus.
 */
std::optional<FocusResolver::FocusChanges> FocusResolver::setInputWindows(
        int32_t displayId, const std::vector<sp<WindowInfoHandle>>& windows) {
    std::string removeFocusReason;

    const std::optional<FocusRequest> request = getFocusRequest(displayId);
    const sp<IBinder> currentFocus = getFocusedWindowToken(displayId);

    // Find the next focused token based on the latest FocusRequest. If the requested focus window
    // cannot be focused, focus will be removed.
    if (request) {
        sp<IBinder> requestedFocus = request->token;
        sp<WindowInfoHandle> resolvedFocusWindow;
        Focusability result = getResolvedFocusWindow(requestedFocus, windows, resolvedFocusWindow);
        if (result == Focusability::OK && resolvedFocusWindow->getToken() == currentFocus) {
            return std::nullopt;
        }
        const Focusability previousResult = mLastFocusResultByDisplay[displayId];
        mLastFocusResultByDisplay[displayId] = result;
        if (result == Focusability::OK) {
            LOG_ALWAYS_FATAL_IF(!resolvedFocusWindow,
                                "Focused window should be non-null when result is OK!");
            return updateFocusedWindow(displayId,
                                       "Window became focusable. Previous reason: " +
                                               ftl::enum_string(previousResult),
                                       resolvedFocusWindow->getToken(),
                                       resolvedFocusWindow->getName());
        }
        removeFocusReason = ftl::enum_string(result);
    }

    // Focused window is no longer focusable and we don't have a suitable focus request to grant.
    // Remove focus if needed.
    return updateFocusedWindow(displayId, removeFocusReason, nullptr);
}

std::optional<FocusResolver::FocusChanges> FocusResolver::setFocusedWindow(
        const FocusRequest& request, const std::vector<sp<WindowInfoHandle>>& windows) {
    const int32_t displayId = request.displayId;
    const sp<IBinder> currentFocus = getFocusedWindowToken(displayId);
    if (currentFocus == request.token) {
        ALOGD_IF(DEBUG_FOCUS,
                 "setFocusedWindow %s on display %" PRId32 " ignored, reason: already focused",
                 request.windowName.c_str(), displayId);
        return std::nullopt;
    }

    sp<WindowInfoHandle> resolvedFocusWindow;
    Focusability result = getResolvedFocusWindow(request.token, windows, resolvedFocusWindow);
    // Update focus request. The focus resolver will always try to handle this request if there is
    // no focused window on the display.
    mFocusRequestByDisplay[displayId] = request;
    mLastFocusResultByDisplay[displayId] = result;

    if (result == Focusability::OK) {
        LOG_ALWAYS_FATAL_IF(!resolvedFocusWindow,
                            "Focused window should be non-null when result is OK!");
        return updateFocusedWindow(displayId, "setFocusedWindow", resolvedFocusWindow->getToken(),
                                   resolvedFocusWindow->getName());
    }

    // The requested window is not currently focusable. Wait for the window to become focusable
    // but remove focus from the current window so that input events can go into a pending queue
    // and be sent to the window when it becomes focused.
    return updateFocusedWindow(displayId, "Waiting for window because " + ftl::enum_string(result),
                               nullptr);
}

FocusResolver::Focusability FocusResolver::getResolvedFocusWindow(
        const sp<IBinder>& token, const std::vector<sp<WindowInfoHandle>>& windows,
        sp<WindowInfoHandle>& outFocusableWindow) {
    sp<IBinder> curFocusCandidate = token;
    bool focusedWindowFound = false;

    // Keep track of all windows reached to prevent a cyclical transferFocus request.
    std::unordered_set<sp<IBinder>, SpHash<IBinder>> tokensReached;

    while (curFocusCandidate != nullptr && tokensReached.count(curFocusCandidate) == 0) {
        tokensReached.emplace(curFocusCandidate);
        Focusability result = isTokenFocusable(curFocusCandidate, windows, outFocusableWindow);
        if (result == Focusability::OK) {
            LOG_ALWAYS_FATAL_IF(!outFocusableWindow,
                                "Focused window should be non-null when result is OK!");
            focusedWindowFound = true;
            // outFocusableWindow has been updated by isTokenFocusable to contain
            // the window info for curFocusCandidate. See if we can grant focus
            // to the token that it wants to transfer its focus to.
            curFocusCandidate = outFocusableWindow->getInfo()->focusTransferTarget;
        }

        // If the initial token is not focusable, return early with the failed result.
        if (!focusedWindowFound) {
            return result;
        }
    }

    return focusedWindowFound ? Focusability::OK : Focusability::NO_WINDOW;
}

FocusResolver::Focusability FocusResolver::isTokenFocusable(
        const sp<IBinder>& token, const std::vector<sp<WindowInfoHandle>>& windows,
        sp<WindowInfoHandle>& outFocusableWindow) {
    bool allWindowsAreFocusable = true;
    bool windowFound = false;
    sp<WindowInfoHandle> visibleWindowHandle = nullptr;
    for (const sp<WindowInfoHandle>& window : windows) {
        if (window->getToken() != token) {
            continue;
        }
        windowFound = true;
        if (!window->getInfo()->inputConfig.test(gui::WindowInfo::InputConfig::NOT_VISIBLE)) {
            // Check if at least a single window is visible.
            visibleWindowHandle = window;
        }
        if (window->getInfo()->inputConfig.test(gui::WindowInfo::InputConfig::NOT_FOCUSABLE)) {
            // Check if all windows with the window token are focusable.
            allWindowsAreFocusable = false;
            break;
        }
    }

    if (!windowFound) {
        return Focusability::NO_WINDOW;
    }
    if (!allWindowsAreFocusable) {
        return Focusability::NOT_FOCUSABLE;
    }
    if (!visibleWindowHandle) {
        return Focusability::NOT_VISIBLE;
    }

    // Only set the outFoundWindow if the window can be focused
    outFocusableWindow = visibleWindowHandle;
    return Focusability::OK;
}

std::optional<FocusResolver::FocusChanges> FocusResolver::updateFocusedWindow(
        int32_t displayId, const std::string& reason, const sp<IBinder>& newFocus,
        const std::string& tokenName) {
    sp<IBinder> oldFocus = getFocusedWindowToken(displayId);
    if (newFocus == oldFocus) {
        return std::nullopt;
    }
    if (newFocus) {
        mFocusedWindowTokenByDisplay[displayId] = {tokenName, newFocus};
    } else {
        mFocusedWindowTokenByDisplay.erase(displayId);
    }

    return {{oldFocus, newFocus, displayId, reason}};
}

std::string FocusResolver::dumpFocusedWindows() const {
    if (mFocusedWindowTokenByDisplay.empty()) {
        return INDENT "FocusedWindows: <none>\n";
    }

    std::string dump;
    dump += INDENT "FocusedWindows:\n";
    for (const auto& [displayId, namedToken] : mFocusedWindowTokenByDisplay) {
        dump += base::StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
                                   namedToken.first.c_str());
    }
    return dump;
}

std::string FocusResolver::dump() const {
    std::string dump = dumpFocusedWindows();
    if (mFocusRequestByDisplay.empty()) {
        return dump + INDENT "FocusRequests: <none>\n";
    }

    dump += INDENT "FocusRequests:\n";
    for (const auto& [displayId, request] : mFocusRequestByDisplay) {
        auto it = mLastFocusResultByDisplay.find(displayId);
        std::string result =
                it != mLastFocusResultByDisplay.end() ? ftl::enum_string(it->second) : "";
        dump += base::StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s' result='%s'\n",
                                   displayId, request.windowName.c_str(), result.c_str());
    }
    return dump;
}

void FocusResolver::displayRemoved(int32_t displayId) {
    mFocusRequestByDisplay.erase(displayId);
    mLastFocusResultByDisplay.erase(displayId);
}

} // namespace android::inputdispatcher
