/*
 * Copyright (C) 2015 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.
 */

#define LOG_TAG "InputDevice"
//#define LOG_NDEBUG 0

// Enables debug output for processing input events
#define DEBUG_INPUT_EVENTS 0

#include "InputDevice.h"

#include <linux/input.h>

#define __STDC_FORMAT_MACROS
#include <cinttypes>
#include <cstdlib>
#include <string>

#include <utils/Log.h>
#include <utils/Timers.h>

#include "InputHost.h"
#include "InputHub.h"
#include "MouseInputMapper.h"
#include "SwitchInputMapper.h"


namespace android {

static InputBus getInputBus(const std::shared_ptr<InputDeviceNode>& node) {
    switch (node->getBusType()) {
        case BUS_USB:
            return INPUT_BUS_USB;
        case BUS_BLUETOOTH:
            return INPUT_BUS_BT;
        case BUS_RS232:
            return INPUT_BUS_SERIAL;
        default:
            // TODO: check for other linux bus types that might not be built-in
            return INPUT_BUS_BUILTIN;
    }
}

static uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses) {
    // Touch devices get dibs on touch-related axes.
    if (deviceClasses & INPUT_DEVICE_CLASS_TOUCH) {
        switch (axis) {
            case ABS_X:
            case ABS_Y:
            case ABS_PRESSURE:
            case ABS_TOOL_WIDTH:
            case ABS_DISTANCE:
            case ABS_TILT_X:
            case ABS_TILT_Y:
            case ABS_MT_SLOT:
            case ABS_MT_TOUCH_MAJOR:
            case ABS_MT_TOUCH_MINOR:
            case ABS_MT_WIDTH_MAJOR:
            case ABS_MT_WIDTH_MINOR:
            case ABS_MT_ORIENTATION:
            case ABS_MT_POSITION_X:
            case ABS_MT_POSITION_Y:
            case ABS_MT_TOOL_TYPE:
            case ABS_MT_BLOB_ID:
            case ABS_MT_TRACKING_ID:
            case ABS_MT_PRESSURE:
            case ABS_MT_DISTANCE:
                return INPUT_DEVICE_CLASS_TOUCH;
        }
    }

    // External stylus gets the pressure axis
    if (deviceClasses & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
        if (axis == ABS_PRESSURE) {
            return INPUT_DEVICE_CLASS_EXTERNAL_STYLUS;
        }
    }

    // Joystick devices get the rest.
    return INPUT_DEVICE_CLASS_JOYSTICK;
}

EvdevDevice::EvdevDevice(InputHostInterface* host, const std::shared_ptr<InputDeviceNode>& node) :
    mHost(host), mDeviceNode(node), mDeviceDefinition(mHost->createDeviceDefinition()) {

    InputBus bus = getInputBus(node);
    mInputId = mHost->createDeviceIdentifier(
            node->getName().c_str(),
            node->getProductId(),
            node->getVendorId(),
            bus,
            node->getUniqueId().c_str());

    createMappers();
    configureDevice();

    // If we found a need for at least one mapper, register the device with the
    // host. If there were no mappers, this device is effectively ignored, as
    // the host won't know about it.
    if (mMappers.size() > 0) {
        mDeviceHandle = mHost->registerDevice(mInputId, mDeviceDefinition);
        for (const auto& mapper : mMappers) {
            mapper->setDeviceHandle(mDeviceHandle);
        }
    }
}

void EvdevDevice::createMappers() {
    // See if this is a cursor device such as a trackball or mouse.
    if (mDeviceNode->hasKey(BTN_MOUSE)
            && mDeviceNode->hasRelativeAxis(REL_X)
            && mDeviceNode->hasRelativeAxis(REL_Y)) {
        mClasses |= INPUT_DEVICE_CLASS_CURSOR;
        mMappers.push_back(std::make_unique<MouseInputMapper>());
    }

    bool isStylus = false;
    bool haveGamepadButtons = mDeviceNode->hasKeyInRange(BTN_MISC, BTN_MOUSE) ||
            mDeviceNode->hasKeyInRange(BTN_JOYSTICK, BTN_DIGI);

    // See if this is a touch pad or stylus.
    // Is this a new modern multi-touch driver?
    if (mDeviceNode->hasAbsoluteAxis(ABS_MT_POSITION_X)
            && mDeviceNode->hasAbsoluteAxis(ABS_MT_POSITION_Y)) {
        // Some joysticks such as the PS3 controller report axes that conflict
        // with the ABS_MT range. Try to confirm that the device really is a
        // touch screen.
        if (mDeviceNode->hasKey(BTN_TOUCH) || !haveGamepadButtons) {
            mClasses |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT;
            //mMappers.push_back(std::make_unique<MultiTouchInputMapper>());
        }
    // Is this an old style single-touch driver?
    } else if (mDeviceNode->hasKey(BTN_TOUCH)
            && mDeviceNode->hasAbsoluteAxis(ABS_X)
            && mDeviceNode->hasAbsoluteAxis(ABS_Y)) {
        mClasses |= INPUT_DEVICE_CLASS_TOUCH;
        //mMappers.push_back(std::make_unique<SingleTouchInputMapper>());
    // Is this a BT stylus?
    } else if ((mDeviceNode->hasAbsoluteAxis(ABS_PRESSURE) || mDeviceNode->hasKey(BTN_TOUCH))
            && !mDeviceNode->hasAbsoluteAxis(ABS_X) && !mDeviceNode->hasAbsoluteAxis(ABS_Y)) {
        mClasses |= INPUT_DEVICE_CLASS_EXTERNAL_STYLUS;
        //mMappers.push_back(std::make_unique<ExternalStylusInputMapper>());
        isStylus = true;
        mClasses &= ~INPUT_DEVICE_CLASS_KEYBOARD;
    }

    // See if this is a keyboard. Ignore everything in the button range except
    // for joystick and gamepad buttons which are handled like keyboards for the
    // most part.
    // Keyboard will try to claim some of the stylus buttons but we really want
    // to reserve those so we can fuse it with the touch screen data. Note this
    // means an external stylus cannot also be a keyboard device.
    if (!isStylus) {
        bool haveKeyboardKeys = mDeviceNode->hasKeyInRange(0, BTN_MISC) ||
            mDeviceNode->hasKeyInRange(KEY_OK, KEY_CNT);
        if (haveKeyboardKeys || haveGamepadButtons) {
            mClasses |= INPUT_DEVICE_CLASS_KEYBOARD;
            //mMappers.push_back(std::make_unique<KeyboardInputMapper>());
        }
    }

    // See if this device is a joystick.
    // Assumes that joysticks always have gamepad buttons in order to
    // distinguish them from other devices such as accelerometers that also have
    // absolute axes.
    if (haveGamepadButtons) {
        uint32_t assumedClasses = mClasses | INPUT_DEVICE_CLASS_JOYSTICK;
        for (int i = 0; i < ABS_CNT; ++i) {
            if (mDeviceNode->hasAbsoluteAxis(i)
                    && getAbsAxisUsage(i, assumedClasses) == INPUT_DEVICE_CLASS_JOYSTICK) {
                mClasses = assumedClasses;
                //mMappers.push_back(std::make_unique<JoystickInputMapper>());
                break;
            }
        }
    }

    // Check whether this device has switches.
    for (int i = 0; i < SW_CNT; ++i) {
        if (mDeviceNode->hasSwitch(i)) {
            mClasses |= INPUT_DEVICE_CLASS_SWITCH;
            mMappers.push_back(std::make_unique<SwitchInputMapper>());
            break;
        }
    }

    // Check whether this device supports the vibrator.
    // TODO: decide if this is necessary.
    if (mDeviceNode->hasForceFeedback(FF_RUMBLE)) {
        mClasses |= INPUT_DEVICE_CLASS_VIBRATOR;
        //mMappers.push_back(std::make_unique<VibratorInputMapper>());
    }

    ALOGD("device %s classes=0x%x %zu mappers", mDeviceNode->getPath().c_str(), mClasses,
            mMappers.size());
}

void EvdevDevice::configureDevice() {
    for (const auto& mapper : mMappers) {
        auto reportDef = mHost->createInputReportDefinition();
        if (mapper->configureInputReport(mDeviceNode.get(), reportDef)) {
            mDeviceDefinition->addReport(reportDef);
        } else {
            mHost->freeReportDefinition(reportDef);
        }

        reportDef = mHost->createOutputReportDefinition();
        if (mapper->configureOutputReport(mDeviceNode.get(), reportDef)) {
            mDeviceDefinition->addReport(reportDef);
        } else {
            mHost->freeReportDefinition(reportDef);
        }
    }
}

void EvdevDevice::processInput(InputEvent& event, nsecs_t currentTime) {
#if DEBUG_INPUT_EVENTS
    std::string log;
    log.append("---InputEvent for device %s---\n");
    log.append("   when:  %" PRId64 "\n");
    log.append("   type:  %d\n");
    log.append("   code:  %d\n");
    log.append("   value: %d\n");
    ALOGD(log.c_str(), mDeviceNode->getPath().c_str(), event.when, event.type, event.code,
            event.value);
#endif

    // Bug 7291243: Add a guard in case the kernel generates timestamps
    // that appear to be far into the future because they were generated
    // using the wrong clock source.
    //
    // This can happen because when the input device is initially opened
    // it has a default clock source of CLOCK_REALTIME.  Any input events
    // enqueued right after the device is opened will have timestamps
    // generated using CLOCK_REALTIME.  We later set the clock source
    // to CLOCK_MONOTONIC but it is already too late.
    //
    // Invalid input event timestamps can result in ANRs, crashes and
    // and other issues that are hard to track down.  We must not let them
    // propagate through the system.
    //
    // Log a warning so that we notice the problem and recover gracefully.
    if (event.when >= currentTime + s2ns(10)) {
        // Double-check. Time may have moved on.
        auto time = systemTime(SYSTEM_TIME_MONOTONIC);
        if (event.when > time) {
            ALOGW("An input event from %s has a timestamp that appears to have "
                    "been generated using the wrong clock source (expected "
                    "CLOCK_MONOTONIC): event time %" PRId64 ", current time %" PRId64
                    ", call time %" PRId64 ". Using current time instead.",
                    mDeviceNode->getPath().c_str(), event.when, time, currentTime);
            event.when = time;
        } else {
            ALOGV("Event time is ok but failed the fast path and required an extra "
                    "call to systemTime: event time %" PRId64 ", current time %" PRId64
                    ", call time %" PRId64 ".", event.when, time, currentTime);
        }
    }

    for (size_t i = 0; i < mMappers.size(); ++i) {
        mMappers[i]->process(event);
    }
}

}  // namespace android
