/*
 * 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;
};

/* 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,
};

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,

    ftl_last = KEYBOARD_BACKLIGHT
};

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);

    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 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; }

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 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;
};

/* 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
