/*
 * Copyright 2022 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 "FakeInputReaderPolicy.h"

#include <android-base/thread_annotations.h>
#include <gtest/gtest.h>

#include "TestConstants.h"
#include "ui/Rotation.h"

namespace android {

void FakeInputReaderPolicy::assertInputDevicesChanged() {
    waitForInputDevices([](bool devicesChanged) {
        if (!devicesChanged) {
            FAIL() << "Timed out waiting for notifyInputDevicesChanged() to be called.";
        }
    });
}

void FakeInputReaderPolicy::assertInputDevicesNotChanged() {
    waitForInputDevices([](bool devicesChanged) {
        if (devicesChanged) {
            FAIL() << "Expected notifyInputDevicesChanged() to not be called.";
        }
    });
}

void FakeInputReaderPolicy::assertStylusGestureNotified(int32_t deviceId) {
    std::scoped_lock lock(mLock);
    ASSERT_TRUE(mStylusGestureNotified);
    ASSERT_EQ(deviceId, *mStylusGestureNotified);
    mStylusGestureNotified.reset();
}

void FakeInputReaderPolicy::assertStylusGestureNotNotified() {
    std::scoped_lock lock(mLock);
    ASSERT_FALSE(mStylusGestureNotified);
}

void FakeInputReaderPolicy::clearViewports() {
    mViewports.clear();
    mConfig.setDisplayViewports(mViewports);
}

std::optional<DisplayViewport> FakeInputReaderPolicy::getDisplayViewportByUniqueId(
        const std::string& uniqueId) const {
    return mConfig.getDisplayViewportByUniqueId(uniqueId);
}
std::optional<DisplayViewport> FakeInputReaderPolicy::getDisplayViewportByType(
        ViewportType type) const {
    return mConfig.getDisplayViewportByType(type);
}

std::optional<DisplayViewport> FakeInputReaderPolicy::getDisplayViewportByPort(
        uint8_t displayPort) const {
    return mConfig.getDisplayViewportByPort(displayPort);
}

void FakeInputReaderPolicy::addDisplayViewport(DisplayViewport viewport) {
    mViewports.push_back(std::move(viewport));
    mConfig.setDisplayViewports(mViewports);
}

void FakeInputReaderPolicy::addDisplayViewport(int32_t displayId, int32_t width, int32_t height,
                                               ui::Rotation orientation, bool isActive,
                                               const std::string& uniqueId,
                                               std::optional<uint8_t> physicalPort,
                                               ViewportType type) {
    const bool isRotated = orientation == ui::ROTATION_90 || orientation == ui::ROTATION_270;
    DisplayViewport v;
    v.displayId = displayId;
    v.orientation = orientation;
    v.logicalLeft = 0;
    v.logicalTop = 0;
    v.logicalRight = isRotated ? height : width;
    v.logicalBottom = isRotated ? width : height;
    v.physicalLeft = 0;
    v.physicalTop = 0;
    v.physicalRight = isRotated ? height : width;
    v.physicalBottom = isRotated ? width : height;
    v.deviceWidth = isRotated ? height : width;
    v.deviceHeight = isRotated ? width : height;
    v.isActive = isActive;
    v.uniqueId = uniqueId;
    v.physicalPort = physicalPort;
    v.type = type;

    addDisplayViewport(v);
}

bool FakeInputReaderPolicy::updateViewport(const DisplayViewport& viewport) {
    size_t count = mViewports.size();
    for (size_t i = 0; i < count; i++) {
        const DisplayViewport& currentViewport = mViewports[i];
        if (currentViewport.displayId == viewport.displayId) {
            mViewports[i] = viewport;
            mConfig.setDisplayViewports(mViewports);
            return true;
        }
    }
    // no viewport found.
    return false;
}

void FakeInputReaderPolicy::addExcludedDeviceName(const std::string& deviceName) {
    mConfig.excludedDeviceNames.push_back(deviceName);
}

void FakeInputReaderPolicy::addInputPortAssociation(const std::string& inputPort,
                                                    uint8_t displayPort) {
    mConfig.portAssociations.insert({inputPort, displayPort});
}

void FakeInputReaderPolicy::addDeviceTypeAssociation(const std::string& inputPort,
                                                     const std::string& type) {
    mConfig.deviceTypeAssociations.insert({inputPort, type});
}

void FakeInputReaderPolicy::addInputUniqueIdAssociation(const std::string& inputUniqueId,
                                                        const std::string& displayUniqueId) {
    mConfig.uniqueIdAssociations.insert({inputUniqueId, displayUniqueId});
}

void FakeInputReaderPolicy::addKeyboardLayoutAssociation(const std::string& inputUniqueId,
                                                         const KeyboardLayoutInfo& layoutInfo) {
    mConfig.keyboardLayoutAssociations.insert({inputUniqueId, layoutInfo});
}

void FakeInputReaderPolicy::addDisabledDevice(int32_t deviceId) {
    mConfig.disabledDevices.insert(deviceId);
}

void FakeInputReaderPolicy::removeDisabledDevice(int32_t deviceId) {
    mConfig.disabledDevices.erase(deviceId);
}

void FakeInputReaderPolicy::setPointerController(
        std::shared_ptr<FakePointerController> controller) {
    mPointerController = std::move(controller);
}

const InputReaderConfiguration& FakeInputReaderPolicy::getReaderConfiguration() const {
    return mConfig;
}

const std::vector<InputDeviceInfo> FakeInputReaderPolicy::getInputDevices() const {
    std::scoped_lock lock(mLock);
    return mInputDevices;
}

TouchAffineTransformation FakeInputReaderPolicy::getTouchAffineTransformation(
        const std::string& inputDeviceDescriptor, ui::Rotation surfaceRotation) {
    return transform;
}

void FakeInputReaderPolicy::setTouchAffineTransformation(const TouchAffineTransformation t) {
    transform = t;
}

PointerCaptureRequest FakeInputReaderPolicy::setPointerCapture(bool enabled) {
    mConfig.pointerCaptureRequest = {enabled, mNextPointerCaptureSequenceNumber++};
    return mConfig.pointerCaptureRequest;
}

void FakeInputReaderPolicy::setShowTouches(bool enabled) {
    mConfig.showTouches = enabled;
}

void FakeInputReaderPolicy::setDefaultPointerDisplayId(int32_t pointerDisplayId) {
    mConfig.defaultPointerDisplayId = pointerDisplayId;
}

void FakeInputReaderPolicy::setPointerGestureEnabled(bool enabled) {
    mConfig.pointerGesturesEnabled = enabled;
}

float FakeInputReaderPolicy::getPointerGestureMovementSpeedRatio() {
    return mConfig.pointerGestureMovementSpeedRatio;
}

float FakeInputReaderPolicy::getPointerGestureZoomSpeedRatio() {
    return mConfig.pointerGestureZoomSpeedRatio;
}

void FakeInputReaderPolicy::setVelocityControlParams(const VelocityControlParameters& params) {
    mConfig.pointerVelocityControlParameters = params;
    mConfig.wheelVelocityControlParameters = params;
}

void FakeInputReaderPolicy::setStylusButtonMotionEventsEnabled(bool enabled) {
    mConfig.stylusButtonMotionEventsEnabled = enabled;
}

void FakeInputReaderPolicy::setStylusPointerIconEnabled(bool enabled) {
    mConfig.stylusPointerIconEnabled = enabled;
}

void FakeInputReaderPolicy::setIsInputMethodConnectionActive(bool active) {
    mIsInputMethodConnectionActive = active;
}

bool FakeInputReaderPolicy::isInputMethodConnectionActive() {
    return mIsInputMethodConnectionActive;
}

void FakeInputReaderPolicy::getReaderConfiguration(InputReaderConfiguration* outConfig) {
    *outConfig = mConfig;
}

std::shared_ptr<PointerControllerInterface> FakeInputReaderPolicy::obtainPointerController(
        int32_t /*deviceId*/) {
    return mPointerController;
}

void FakeInputReaderPolicy::notifyInputDevicesChanged(
        const std::vector<InputDeviceInfo>& inputDevices) {
    std::scoped_lock lock(mLock);
    mInputDevices = inputDevices;
    mInputDevicesChanged = true;
    mDevicesChangedCondition.notify_all();
}

std::shared_ptr<KeyCharacterMap> FakeInputReaderPolicy::getKeyboardLayoutOverlay(
        const InputDeviceIdentifier&, const std::optional<KeyboardLayoutInfo>) {
    return nullptr;
}

std::string FakeInputReaderPolicy::getDeviceAlias(const InputDeviceIdentifier&) {
    return "";
}

void FakeInputReaderPolicy::waitForInputDevices(std::function<void(bool)> processDevicesChanged) {
    std::unique_lock<std::mutex> lock(mLock);
    base::ScopedLockAssertion assumeLocked(mLock);

    const bool devicesChanged =
            mDevicesChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
                return mInputDevicesChanged;
            });
    ASSERT_NO_FATAL_FAILURE(processDevicesChanged(devicesChanged));
    mInputDevicesChanged = false;
}

void FakeInputReaderPolicy::notifyStylusGestureStarted(int32_t deviceId, nsecs_t eventTime) {
    std::scoped_lock lock(mLock);
    mStylusGestureNotified = deviceId;
}

std::optional<DisplayViewport> FakeInputReaderPolicy::getPointerViewportForAssociatedDisplay(
        int32_t associatedDisplayId) {
    if (associatedDisplayId == ADISPLAY_ID_NONE) {
        associatedDisplayId = mConfig.defaultPointerDisplayId;
    }
    for (auto& viewport : mViewports) {
        if (viewport.displayId == associatedDisplayId) {
            return std::make_optional(viewport);
        }
    }
    return std::nullopt;
}

} // namespace android
