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

#pragma once

#include <android/sensor.h>
#include <ftl/flags.h>
#include <ftl/mixins.h>
#include <input/Input.h>
#include <input/KeyCharacterMap.h>
#include <set>
#include <unordered_map>
#include <vector>

#include <android/os/IInputConstants.h>

namespace android {

/*
 * Identifies a device.
 */
struct InputDeviceIdentifier {
    inline InputDeviceIdentifier() :
            bus(0), vendor(0), product(0), version(0) {
    }

    // Information provided by the kernel.
    std::string name;
    std::string location;
    std::string uniqueId;
    uint16_t bus;
    uint16_t vendor;
    uint16_t product;
    uint16_t version;

    // A composite input device descriptor string that uniquely identifies the device
    // even across reboots or reconnections.  The value of this field is used by
    // upper layers of the input system to associate settings with individual devices.
    // It is hashed from whatever kernel provided information is available.
    // Ideally, the way this value is computed should not change between Android releases
    // because that would invalidate persistent settings that rely on it.
    std::string descriptor;

    // A value added to uniquely identify a device in the absence of a unique id. This
    // is intended to be a minimum way to distinguish from other active devices and may
    // reuse values that are not associated with an input anymore.
    uint16_t nonce;

    // The bluetooth address of the device, if known.
    std::optional<std::string> bluetoothAddress;

    /**
     * Return InputDeviceIdentifier.name that has been adjusted as follows:
     *     - all characters besides alphanumerics, dash,
     *       and underscore have been replaced with underscores.
     * This helps in situations where a file that matches the device name is needed,
     * while conforming to the filename limitations.
     */
    std::string getCanonicalName() const;

    bool operator==(const InputDeviceIdentifier&) const = default;
    bool operator!=(const InputDeviceIdentifier&) const = default;
};

/**
 * Holds View related behaviors for an InputDevice.
 */
struct InputDeviceViewBehavior {
    /**
     * The smooth scroll behavior that applies for all source/axis, if defined by the device.
     * Empty optional if the device has not specified the default smooth scroll behavior.
     */
    std::optional<bool> shouldSmoothScroll;
};

/* Types of input device sensors. Keep sync with core/java/android/hardware/Sensor.java */
enum class InputDeviceSensorType : int32_t {
    ACCELEROMETER = ASENSOR_TYPE_ACCELEROMETER,
    MAGNETIC_FIELD = ASENSOR_TYPE_MAGNETIC_FIELD,
    ORIENTATION = 3,
    GYROSCOPE = ASENSOR_TYPE_GYROSCOPE,
    LIGHT = ASENSOR_TYPE_LIGHT,
    PRESSURE = ASENSOR_TYPE_PRESSURE,
    TEMPERATURE = 7,
    PROXIMITY = ASENSOR_TYPE_PROXIMITY,
    GRAVITY = ASENSOR_TYPE_GRAVITY,
    LINEAR_ACCELERATION = ASENSOR_TYPE_LINEAR_ACCELERATION,
    ROTATION_VECTOR = ASENSOR_TYPE_ROTATION_VECTOR,
    RELATIVE_HUMIDITY = ASENSOR_TYPE_RELATIVE_HUMIDITY,
    AMBIENT_TEMPERATURE = ASENSOR_TYPE_AMBIENT_TEMPERATURE,
    MAGNETIC_FIELD_UNCALIBRATED = ASENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
    GAME_ROTATION_VECTOR = ASENSOR_TYPE_GAME_ROTATION_VECTOR,
    GYROSCOPE_UNCALIBRATED = ASENSOR_TYPE_GYROSCOPE_UNCALIBRATED,
    SIGNIFICANT_MOTION = ASENSOR_TYPE_SIGNIFICANT_MOTION,

    ftl_first = ACCELEROMETER,
    ftl_last = SIGNIFICANT_MOTION
};

enum class InputDeviceSensorAccuracy : int32_t {
    ACCURACY_NONE = 0,
    ACCURACY_LOW = 1,
    ACCURACY_MEDIUM = 2,
    ACCURACY_HIGH = 3,

    ftl_last = ACCURACY_HIGH,
};

enum class InputDeviceSensorReportingMode : int32_t {
    CONTINUOUS = 0,
    ON_CHANGE = 1,
    ONE_SHOT = 2,
    SPECIAL_TRIGGER = 3,
};

enum class InputDeviceLightType : int32_t {
    INPUT = 0,
    PLAYER_ID = 1,
    KEYBOARD_BACKLIGHT = 2,
    KEYBOARD_MIC_MUTE = 3,

    ftl_last = KEYBOARD_MIC_MUTE
};

enum class InputDeviceLightCapability : uint32_t {
    /** Capability to change brightness of the light */
    BRIGHTNESS = 0x00000001,
    /** Capability to change color of the light */
    RGB = 0x00000002,
};

struct InputDeviceSensorInfo {
    explicit InputDeviceSensorInfo(std::string name, std::string vendor, int32_t version,
                                   InputDeviceSensorType type, InputDeviceSensorAccuracy accuracy,
                                   float maxRange, float resolution, float power, int32_t minDelay,
                                   int32_t fifoReservedEventCount, int32_t fifoMaxEventCount,
                                   std::string stringType, int32_t maxDelay, int32_t flags,
                                   int32_t id)
          : name(name),
            vendor(vendor),
            version(version),
            type(type),
            accuracy(accuracy),
            maxRange(maxRange),
            resolution(resolution),
            power(power),
            minDelay(minDelay),
            fifoReservedEventCount(fifoReservedEventCount),
            fifoMaxEventCount(fifoMaxEventCount),
            stringType(stringType),
            maxDelay(maxDelay),
            flags(flags),
            id(id) {}
    // Name string of the sensor.
    std::string name;
    // Vendor string of this sensor.
    std::string vendor;
    // Version of the sensor's module.
    int32_t version;
    // Generic type of this sensor.
    InputDeviceSensorType type;
    // The current accuracy of sensor event.
    InputDeviceSensorAccuracy accuracy;
    // Maximum range of the sensor in the sensor's unit.
    float maxRange;
    // Resolution of the sensor in the sensor's unit.
    float resolution;
    // The power in mA used by this sensor while in use.
    float power;
    // The minimum delay allowed between two events in microsecond or zero if this sensor only
    // returns a value when the data it's measuring changes.
    int32_t minDelay;
    // Number of events reserved for this sensor in the batch mode FIFO.
    int32_t fifoReservedEventCount;
    // Maximum number of events of this sensor that could be batched.
    int32_t fifoMaxEventCount;
    // The type of this sensor as a string.
    std::string stringType;
    // The delay between two sensor events corresponding to the lowest frequency that this sensor
    // supports.
    int32_t maxDelay;
    // Sensor flags
    int32_t flags;
    // Sensor id, same as the input device ID it belongs to.
    int32_t id;
};

struct BrightnessLevel : ftl::DefaultConstructible<BrightnessLevel, std::uint8_t>,
                         ftl::Equatable<BrightnessLevel>,
                         ftl::Orderable<BrightnessLevel>,
                         ftl::Addable<BrightnessLevel> {
    using DefaultConstructible::DefaultConstructible;
};

struct InputDeviceLightInfo {
    explicit InputDeviceLightInfo(std::string name, int32_t id, InputDeviceLightType type,
                                  ftl::Flags<InputDeviceLightCapability> capabilityFlags,
                                  int32_t ordinal,
                                  std::set<BrightnessLevel> preferredBrightnessLevels)
          : name(name),
            id(id),
            type(type),
            capabilityFlags(capabilityFlags),
            ordinal(ordinal),
            preferredBrightnessLevels(std::move(preferredBrightnessLevels)) {}
    // Name string of the light.
    std::string name;
    // Light id
    int32_t id;
    // Type of the light.
    InputDeviceLightType type;
    // Light capabilities.
    ftl::Flags<InputDeviceLightCapability> capabilityFlags;
    // Ordinal of the light
    int32_t ordinal;
    // Custom brightness levels for the light
    std::set<BrightnessLevel> preferredBrightnessLevels;
};

struct InputDeviceBatteryInfo {
    explicit InputDeviceBatteryInfo(std::string name, int32_t id) : name(name), id(id) {}
    // Name string of the battery.
    std::string name;
    // Battery id
    int32_t id;
};

struct KeyboardLayoutInfo {
    explicit KeyboardLayoutInfo(std::string languageTag, std::string layoutType)
          : languageTag(languageTag), layoutType(layoutType) {}

    // A BCP 47 conformant language tag such as "en-US".
    std::string languageTag;
    // The layout type such as QWERTY or AZERTY.
    std::string layoutType;

    inline bool operator==(const KeyboardLayoutInfo& other) const {
        return languageTag == other.languageTag && layoutType == other.layoutType;
    }
    inline bool operator!=(const KeyboardLayoutInfo& other) const { return !(*this == other); }
};

// The version of the Universal Stylus Initiative (USI) protocol supported by the input device.
struct InputDeviceUsiVersion {
    int32_t majorVersion = -1;
    int32_t minorVersion = -1;
};

/*
 * Describes the characteristics and capabilities of an input device.
 */
class InputDeviceInfo {
public:
    InputDeviceInfo();
    InputDeviceInfo(const InputDeviceInfo& other);
    ~InputDeviceInfo();

    struct MotionRange {
        int32_t axis;
        uint32_t source;
        float min;
        float max;
        float flat;
        float fuzz;
        float resolution;
    };

    void initialize(int32_t id, int32_t generation, int32_t controllerNumber,
                    const InputDeviceIdentifier& identifier, const std::string& alias,
                    bool isExternal, bool hasMic, int32_t associatedDisplayId,
                    InputDeviceViewBehavior viewBehavior = {{}}, bool enabled = true);

    inline int32_t getId() const { return mId; }
    inline int32_t getControllerNumber() const { return mControllerNumber; }
    inline int32_t getGeneration() const { return mGeneration; }
    inline const InputDeviceIdentifier& getIdentifier() const { return mIdentifier; }
    inline const std::string& getAlias() const { return mAlias; }
    inline const std::string& getDisplayName() const {
        return mAlias.empty() ? mIdentifier.name : mAlias;
    }
    inline bool isExternal() const { return mIsExternal; }
    inline bool hasMic() const { return mHasMic; }
    inline uint32_t getSources() const { return mSources; }

    const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;

    void addSource(uint32_t source);
    void addMotionRange(int32_t axis, uint32_t source,
            float min, float max, float flat, float fuzz, float resolution);
    void addMotionRange(const MotionRange& range);
    void addSensorInfo(const InputDeviceSensorInfo& info);
    void addBatteryInfo(const InputDeviceBatteryInfo& info);
    void addLightInfo(const InputDeviceLightInfo& info);

    void setKeyboardType(int32_t keyboardType);
    inline int32_t getKeyboardType() const { return mKeyboardType; }

    void setKeyboardLayoutInfo(KeyboardLayoutInfo keyboardLayoutInfo);
    inline const std::optional<KeyboardLayoutInfo>& getKeyboardLayoutInfo() const {
        return mKeyboardLayoutInfo;
    }

    inline const InputDeviceViewBehavior& getViewBehavior() const { return mViewBehavior; }

    inline void setKeyCharacterMap(const std::shared_ptr<KeyCharacterMap> value) {
        mKeyCharacterMap = value;
    }

    inline const std::shared_ptr<KeyCharacterMap> getKeyCharacterMap() const {
        return mKeyCharacterMap;
    }

    inline void setVibrator(bool hasVibrator) { mHasVibrator = hasVibrator; }
    inline bool hasVibrator() const { return mHasVibrator; }

    inline void setHasBattery(bool hasBattery) { mHasBattery = hasBattery; }
    inline bool hasBattery() const { return mHasBattery; }

    inline void setButtonUnderPad(bool hasButton) { mHasButtonUnderPad = hasButton; }
    inline bool hasButtonUnderPad() const { return mHasButtonUnderPad; }

    inline void setHasSensor(bool hasSensor) { mHasSensor = hasSensor; }
    inline bool hasSensor() const { return mHasSensor; }

    inline const std::vector<MotionRange>& getMotionRanges() const {
        return mMotionRanges;
    }

    std::vector<InputDeviceSensorInfo> getSensors();

    std::vector<InputDeviceLightInfo> getLights();

    inline void setUsiVersion(std::optional<InputDeviceUsiVersion> usiVersion) {
        mUsiVersion = std::move(usiVersion);
    }
    inline std::optional<InputDeviceUsiVersion> getUsiVersion() const { return mUsiVersion; }

    inline int32_t getAssociatedDisplayId() const { return mAssociatedDisplayId; }

    inline void setEnabled(bool enabled) { mEnabled = enabled; }
    inline bool isEnabled() const { return mEnabled; }

private:
    int32_t mId;
    int32_t mGeneration;
    int32_t mControllerNumber;
    InputDeviceIdentifier mIdentifier;
    std::string mAlias;
    bool mIsExternal;
    bool mHasMic;
    std::optional<KeyboardLayoutInfo> mKeyboardLayoutInfo;
    uint32_t mSources;
    int32_t mKeyboardType;
    std::shared_ptr<KeyCharacterMap> mKeyCharacterMap;
    std::optional<InputDeviceUsiVersion> mUsiVersion;
    int32_t mAssociatedDisplayId;
    bool mEnabled;

    bool mHasVibrator;
    bool mHasBattery;
    bool mHasButtonUnderPad;
    bool mHasSensor;

    std::vector<MotionRange> mMotionRanges;
    std::unordered_map<InputDeviceSensorType, InputDeviceSensorInfo> mSensors;
    /* Map from light ID to light info */
    std::unordered_map<int32_t, InputDeviceLightInfo> mLights;
    /* Map from battery ID to battery info */
    std::unordered_map<int32_t, InputDeviceBatteryInfo> mBatteries;
    /** The View related behaviors for the device. */
    InputDeviceViewBehavior mViewBehavior;
};

/* Types of input device configuration files. */
enum class InputDeviceConfigurationFileType : int32_t {
    CONFIGURATION = 0,     /* .idc file */
    KEY_LAYOUT = 1,        /* .kl file */
    KEY_CHARACTER_MAP = 2, /* .kcm file */
};

/*
 * Gets the path of an input device configuration file, if one is available.
 * Considers both system provided and user installed configuration files.
 * The optional suffix is appended to the end of the file name (before the
 * extension).
 *
 * The device identifier is used to construct several default configuration file
 * names to try based on the device name, vendor, product, and version.
 *
 * Returns an empty string if not found.
 */
extern std::string getInputDeviceConfigurationFilePathByDeviceIdentifier(
        const InputDeviceIdentifier& deviceIdentifier, InputDeviceConfigurationFileType type,
        const char* suffix = "");

/*
 * Gets the path of an input device configuration file, if one is available.
 * Considers both system provided and user installed configuration files.
 *
 * The name is case-sensitive and is used to construct the filename to resolve.
 * All characters except 'a'-'z', 'A'-'Z', '0'-'9', '-', and '_' are replaced by underscores.
 *
 * Returns an empty string if not found.
 */
extern std::string getInputDeviceConfigurationFilePathByName(
        const std::string& name, InputDeviceConfigurationFileType type);

enum ReservedInputDeviceId : int32_t {
    // Device id representing an invalid device
    INVALID_INPUT_DEVICE_ID = android::os::IInputConstants::INVALID_INPUT_DEVICE_ID,
    // Device id of a special "virtual" keyboard that is always present.
    VIRTUAL_KEYBOARD_ID = -1,
    // Device id of the "built-in" keyboard if there is one.
    BUILT_IN_KEYBOARD_ID = 0,
    // First device id available for dynamic devices
    END_RESERVED_ID = 1,
};

} // namespace android
