// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.hardware.input;

using zx;

alias ReportId = uint8;

const MAX_DESC_LEN uint16 = 8192;
const MAX_REPORT_LEN uint16 = 8192;
const MAX_REPORT_DATA uint16 = 8192;
const MAX_REPORTS_COUNT uint32 = 50;

type ReportType = strict enum : uint8 {
    INPUT = 1;
    OUTPUT = 2;
    FEATURE = 3;
};

/// Each `DeviceReportsReader` has its own FIFO of reports in the driver.
/// Calling `ReadReports` drains the Report FIFO. If the Report FIFO fills up
/// between calls to `ReadReports` the channel will be closed.
closed protocol DeviceReportsReader {
    /// This is a Hanging-Get function to read the reports in the Report FIFO.
    /// This will block until there is at least one report available.
    /// If there is already one outstanding Hanging-Get, calling this again will
    /// return ZX_ERR_ALREADY_BOUND.
    strict ReadReports() -> (struct {
        reports vector<@generated_name("Report") struct {
            /// The time the report was created, from the view of the monotonic
            /// clock.
            time zx.Time;
            /// The HID report data. This is guaranteed to always be a full HID
            /// report.
            data vector<uint8>:MAX_REPORT_DATA;
        }>:MAX_REPORTS_COUNT;
    }) error zx.Status;
};

// TODO(https://fxbug.dev/42126285): This API doesn't follow best practices and needs to be
// cleaned up.
closed protocol Device {
    /// Get the HID boot interface protocol this device supports
    strict GetBootProtocol() -> (struct {
        protocol @generated_name("BootProtocol") strict enum : uint32 {
            NONE = 0;
            KBD = 1;
            MOUSE = 2;
        };
    });

    /// Get the Device's IDs.
    ///
    /// If this is a real HID device, then the id information will come from the
    /// device itself. Mock HID devices may assign the ids in the driver. If the
    /// mock HID driver does not assign ids, zeros will be used instead.
    strict GetDeviceIds() -> (struct {
        ids @generated_name("DeviceIds") struct {
            vendor_id uint32;
            product_id uint32;
            version uint32;
        };
    });

    /// Get the report descriptor
    strict GetReportDesc() -> (struct {
        desc vector<uint8>:MAX_DESC_LEN;
    });

    /// Open a new DeviceReportsReader on this device. Opening a DeviceReportsReader
    /// allocates a new FIFO for receiving input reports.
    strict GetDeviceReportsReader(resource struct {
        reader server_end:DeviceReportsReader;
    }) -> () error zx.Status;

    /// Read one report out of the report FIFO. Only a single report will be
    /// returned in this API. `time` is the time the report was created, from
    /// the view of the monotonic clock.
    /// If status is ZX_ERR_SHOULD_WAIT the client can wait on the event
    /// from `GetReportsEvent`.
    strict ReadReport() -> (struct {
        status zx.Status;
        data vector<uint8>:MAX_REPORT_DATA;
        time zx.Time;
    });

    /// Read up to MAX_REPORT_DATA bytes of reports that have been sent from a device.
    /// This is the interface that is supposed to be used for continuous polling.
    /// Multiple reports can be returned from this API at a time, it is up to the client
    /// to do the parsing of the reports with the correct sizes and offset.
    /// It is guaranteed that only whole reports will be sent.
    /// If there are no reports, this will return ZX_ERR_SHOULD_WAIT, and the client can
    /// wait on the event from `GetReportsEvent`.
    strict ReadReports() -> (struct {
        status zx.Status;
        data vector<uint8>:MAX_REPORT_DATA;
    });

    /// Receive an event that will signal on `ZX_USER_SIGNAL_0` when there are reports in the
    /// Device's report FIFO. This signal will be de-asserted when there are no
    /// reports in the Device's report FIFO. This event can be re-used each time
    /// the client wishes to know if there are reports in the FIFO.
    strict GetReportsEvent() -> (resource struct {
        status zx.Status;
        event zx.Handle:EVENT;
    });

    /// Send a request to the hardware for a given report described by type and id.
    /// Returns the hardware's response. This interface is not intended
    /// to be used for continuous polling of the reports.
    strict GetReport(struct {
        type ReportType;
        id ReportId;
    }) -> (struct {
        status zx.Status;
        report vector<uint8>:MAX_REPORT_LEN;
    });

    /// Set a single report of the given (type, id) pair.
    strict SetReport(struct {
        type ReportType;
        id ReportId;
        report vector<uint8>:MAX_REPORT_LEN;
    }) -> (struct {
        status zx.Status;
    });

    /// Set the trace ID that is used for HID report flow events.
    strict SetTraceId(struct {
        id uint32;
    });
};

closed protocol Controller {
    /// Opens a new session on the device.
    strict OpenSession(resource struct {
        session server_end:Device;
    });
};
