#include <app/zedmon/usb.h>

#include <assert.h>
#include <app/zedmon/ina.h>
#include <app/zedmon/usb_proto.h>
#include <lk/debug.h>
#include <dev/udc.h>
#include <dev/usb.h>
#include <dev/usbc.h>
#include <lk/err.h>
#include <kernel/mutex.h>
#include <kernel/port.h>
#include <kernel/thread.h>
#include <lib/cbuf.h>
#include <lib/console.h>
#include <platform.h>
#include <stdint.h>
#include <string.h>
#include <target/parameters.h>
#include <lk/trace.h>

#define DATA_IN_EP_ADDR_OFFSET (0x0B)
#define DATA_OUT_EP_ADDR_OFFSET (0x12)

#define W(w) (w & 0xff), (w >> 8)

static uint8_t zedmon_if_descriptor[] = {
    0x09,           /* length */
    INTERFACE,      /* type */
    0x00,           /* interface num */
    0x00,           /* alternates */
    0x02,           /* endpoint count */
    0xff,           /* interface class */
    0xff,           /* interface subclass */
    0x00,           /* interface protocol */
    0x00,           /* string index */

    /* endpoint 1 IN */
    0x07,           /* length */
    ENDPOINT,       /* type */
    0x83,           /* address: 1 IN */
    0x02,           /* type: bulk */
    W(64),          /* max packet size: 64 */
    00,             /* interval */

    /* endpoint 1 OUT */
    0x07,           /* length */
    ENDPOINT,       /* type */
    0x03,           /* address: 1 OUT */
    0x02,           /* type: bulk */
    W(64),          /* max packet size: 64 */
    00,             /* interval */
};

static zedmon_usb_report_format_t zedmon_report_formats[] = {
    {
        .packet_type = ZEDMON_USB_PACKET_REPORT_FORMAT,
        .index = 0,
        .type = ZEDMON_USB_TYPE_INT16,
        .unit = ZEDMON_USB_UNIT_VOLTS,
        .scale = 2.5e-6f,
        .name = "v_shunt",
    },
    {
        .packet_type = ZEDMON_USB_PACKET_REPORT_FORMAT,
        .index = 1,
        .type = ZEDMON_USB_TYPE_INT16,
        .unit = ZEDMON_USB_UNIT_VOLTS,
        .scale = 1.25e-3f,
        .name = "v_bus",
    },
    {
        .packet_type = ZEDMON_USB_PACKET_REPORT_FORMAT,
        .index = 0xff,
        .type = 0,
        .unit = 0,
        .scale =0.0f,
        .name = "",
    },
};

static zedmon_usb_parameter_value_t zedmon_parameter_values[] = {
    {
        .packet_type = ZEDMON_USB_PACKET_PARAMETER_VALUE,
        .name = "shunt_resistance",
        .data_type = ZEDMON_USB_TYPE_FLOAT32,
        .data.float_value = SHUNT_RESISTANCE,
    },
    {
        .packet_type = ZEDMON_USB_PACKET_PARAMETER_VALUE,
        .name = "",
        .data_type = ZEDMON_USB_TYPE_UINT8,
        .data.bytes = {0},
    }
};

typedef struct __attribute__((packed)) {
    lk_bigtime_t timestamp;
    uint16_t     v_shunt;
    uint16_t     v_bus;
} zedmon_sample_t;

static_assert(sizeof(zedmon_sample_t) == 12);
static_assert(offsetof(zedmon_sample_t, timestamp) == 0);
static_assert(offsetof(zedmon_sample_t, v_shunt) == 8);
static_assert(offsetof(zedmon_sample_t, v_bus) == 10);

typedef struct __attribute__((packed)) {
    uint8_t         packet_type;
    zedmon_sample_t samples[5];
} zedmon_report_packet_t;
static_assert(sizeof(zedmon_report_packet_t) <= 64);

typedef struct __attribute__((packed)) {
    uint8_t packet_type;
    uint64_t timestamp;
} zedmon_timestamp_packet_t;

static cbuf_t zedmon_sample_cbuf;

static int zedmon_ep;

typedef enum {
    ZEDMON_PORT_CTX_USB_RX     = 0x0,
    ZEDMON_PORT_CTX_USB_TX     = 0x1,
    ZEDMON_PORT_CTX_USB_SAMPLE = 0x2,
} zedmon_port_context_t;

static port_t zedmon_usb_rx_port;
static port_t zedmon_usb_tx_port;
static port_t zedmon_usb_sample_port;
static port_t zedmon_usb_port_group;

static thread_t *zedmon_usb_thread;
static bool zedmon_tx_busy;

static bool zedmon_usb_reporting_enabled;
static zedmon_report_packet_t zedmon_usb_report_packet;
static zedmon_timestamp_packet_t zedmon_usb_timestamp_packet;


static status_t ep_cb_rx(ep_t endpoint, usbc_transfer_t *t);
static status_t ep_cb_tx(ep_t endpoint, usbc_transfer_t *t);

static void queue_rx(void)
{
    static usbc_transfer_t transfer;
    static uint8_t buf[512];

    transfer.callback = &ep_cb_rx;
    transfer.result = 0;
    transfer.buf = &buf;
    transfer.buflen = sizeof(buf);
    transfer.bufpos = 0;
    transfer.extra = 0;

    usbc_queue_rx(zedmon_ep, &transfer);
}

static status_t queue_tx(void *data, size_t len)
{
    if (zedmon_tx_busy) {
        return ERR_BUSY;
    }

    static usbc_transfer_t transfer;
    transfer.callback = &ep_cb_tx;
    transfer.result = 0;
    transfer.buf = data;
    transfer.buflen = len;
    transfer.bufpos = 0;
    transfer.extra = 0;

    zedmon_tx_busy = true;
    usbc_queue_tx(zedmon_ep, &transfer);
    return NO_ERROR;
}

static status_t ep_cb_rx(ep_t endpoint, usbc_transfer_t *t)
{
#if LOCAL_TRACE
    LTRACEF("ep %u transfer %p\n", endpoint, t);
    usbc_dump_transfer(t);

    if (t->result >= 0) {
        hexdump8(t->buf, t->bufpos);
    }
#endif

    //printf("ep %u transfer %p\n", endpoint, t);

    if (t->result >= 0) {
        if (t->bufpos >= 1) {
            port_packet_t packet;
            int command_length =
                t->bufpos < sizeof(packet.value) ? t->bufpos : sizeof(packet.value);
            memcpy(&packet.value, t->buf, command_length);
            port_write(zedmon_usb_rx_port, &packet, 1);
        }
        queue_rx();
    } else {
        printf("bad rx\n");
    }


    return NO_ERROR;
}

static status_t ep_cb_tx(ep_t endpoint, usbc_transfer_t *t)
{
    //printf("ep %u transfer %p\n", endpoint, t);
#if LOCAL_TRACE
    LTRACEF("ep %u transfer %p\n", endpoint, t);
    usbc_dump_transfer(t);
#endif

    if (t->result >= 0) {
        port_packet_t packet;
        packet.value[0] = 0x0;
        port_write(zedmon_usb_tx_port, &packet, 1);
    } else {
        printf("bad tx\n");
    }
    return NO_ERROR;
}


static status_t zedmon_usb_callback(void *cookie, usb_callback_op_t op,
                                    const union usb_callback_args *args)
{
#if LOCAL_TRACE
    LTRACEF("cookie %p, op %u, args %p\n", cookie, op, args);
#endif

    if (op == USB_CB_ONLINE) {
        usbc_setup_endpoint(zedmon_ep, USB_IN, 0x40, USB_BULK);
        usbc_setup_endpoint(zedmon_ep, USB_OUT, 0x40, USB_BULK);

        queue_rx();
    } else if (op == USB_CB_SETUP_MSG) {
        zedmon_usb_reporting_enabled = false;
    }
    return NO_ERROR;
}


static void zedmon_usb_handle_query_report_format_packet(const uint8_t values[7]) {
    uint8_t index = values[0];

    if (index >= countof(zedmon_report_formats)) {
        index = countof(zedmon_report_formats) - 1;
    }

    queue_tx(&zedmon_report_formats[index], sizeof(zedmon_report_formats[index]));
}

static void zedmon_usb_handle_query_parameter_value_packet(const uint8_t values[7]) {
    uint8_t index = values[0];

    if (index >= countof(zedmon_parameter_values)) {
        index = countof(zedmon_parameter_values) - 1;
    }

    queue_tx(&zedmon_parameter_values[index], sizeof(zedmon_parameter_values[index]));
}

static void zedmon_usb_handle_set_output_packet(const uint8_t values[7]) {
    zedmon_usb_set_target_out(values[0], values[1]);
}

static void zedmon_usb_handle_usb_rx_port(const port_packet_t *packet) {
    zedmon_usb_packet_type_t type = (zedmon_usb_packet_type_t)packet->value[0];

    switch (type) {
        case ZEDMON_USB_PACKET_QUERY_REPORT_FORMAT:
            zedmon_usb_handle_query_report_format_packet((const uint8_t *)packet->value + 1);
            break;
        case ZEDMON_USB_PACKET_QUERY_TIME:
            zedmon_usb_timestamp_packet.packet_type = ZEDMON_USB_PACKET_TIMESTAMP;
            zedmon_usb_timestamp_packet.timestamp = ina_get_current_time();
            queue_tx(&zedmon_usb_timestamp_packet, sizeof(zedmon_usb_timestamp_packet));
            break;
        case ZEDMON_USB_PACKET_QUERY_PARAMETER_VALUE:
            zedmon_usb_handle_query_parameter_value_packet((const uint8_t *)packet->value + 1);
            break;
        case ZEDMON_USB_PACKET_ENABLE_REPORTING:
            zedmon_usb_reporting_enabled = true;
            break;
        case ZEDMON_USB_PACKET_DISABLE_REPORTING:
            zedmon_usb_reporting_enabled = false;
            break;
        case ZEDMON_USB_PACKET_SET_OUTPUT:
            zedmon_usb_handle_set_output_packet((const uint8_t *)packet->value + 1);
            break;

            // These are Device -> Host packets which we should never see.
        case ZEDMON_USB_PACKET_REPORT_FORMAT:
            break;
        case ZEDMON_USB_PACKET_REPORT:
            break;
        case ZEDMON_USB_PACKET_TIMESTAMP:
            break;
        case ZEDMON_USB_PACKET_PARAMETER_VALUE:
            break;
    }
}

static void zedmon_usb_check_for_repot_tx(void) {
    if (zedmon_tx_busy) {
        return;
    }
    zedmon_report_packet_t *packet = &zedmon_usb_report_packet;
    if (cbuf_space_used(&zedmon_sample_cbuf) >= sizeof(packet->samples)) {
        size_t read_len =
            cbuf_read(&zedmon_sample_cbuf, &packet->samples, sizeof(packet->samples), false);
        assert(read_len == sizeof(packet->samples));

        if (zedmon_usb_reporting_enabled) {
            queue_tx(packet, sizeof(*packet));
        }
    }
}

static int zedmon_usb_thread_entry(void *arg) {
    while (true) {
        port_result_t result;
        port_read(zedmon_usb_port_group, INFINITE_TIME, &result);
        zedmon_port_context_t context = (zedmon_port_context_t)result.ctx;
        switch(context) {
            case ZEDMON_PORT_CTX_USB_RX:
                zedmon_usb_handle_usb_rx_port(&result.packet);
                break;

            case ZEDMON_PORT_CTX_USB_TX:
                zedmon_tx_busy = false;
                zedmon_usb_check_for_repot_tx();
                break;

            case ZEDMON_PORT_CTX_USB_SAMPLE:
                zedmon_usb_check_for_repot_tx();
                break;

        }
    }
    return 0;

}

void zedmon_usb_add_sample(lk_bigtime_t timestamp, uint16_t v_shunt, uint16_t v_bus) {
    zedmon_sample_t sample = {
        .timestamp = timestamp,
        .v_shunt   = v_shunt,
        .v_bus     = v_bus,
    };

    // If there's no space, drop the sample.
    if (cbuf_space_avail(&zedmon_sample_cbuf) < sizeof(sample)) {
        return;
    }
    size_t write_len = cbuf_write(&zedmon_sample_cbuf, &sample, sizeof(sample), false);
    assert(write_len == sizeof(sample));

    port_packet_t packet;
    packet.value[0] = 0x0;
    port_write(zedmon_usb_sample_port, &packet, 1);
}

void __WEAK zedmon_usb_set_target_out(int index, bool value) {
}

void zedmon_usb_init(int data_ep_addr) {
    cbuf_initialize(&zedmon_sample_cbuf, 128);
    zedmon_usb_report_packet.packet_type = ZEDMON_USB_PACKET_REPORT;

    status_t ret;

    ret = port_create("zm_usb_rx", PORT_MODE_UNICAST, &zedmon_usb_rx_port);
    if (ret != NO_ERROR) {
        printf("error creating zm_usb_rx: %d\n", ret);
    }

    port_t usb_rx_reader;
    ret = port_open("zm_usb_rx", (void *)ZEDMON_PORT_CTX_USB_RX, &usb_rx_reader);
    if (ret != NO_ERROR) {
        printf("error opening zm_usb_rx: %d\n", ret);
    }

    ret = port_create("zm_usb_tx", PORT_MODE_UNICAST, &zedmon_usb_tx_port);
    if (ret != NO_ERROR) {
        printf("error creating zm_usb_rx: %d\n", ret);
    }

    port_t usb_tx_reader;
    ret = port_open("zm_usb_tx", (void *)ZEDMON_PORT_CTX_USB_TX, &usb_tx_reader);
    if (ret != NO_ERROR) {
        printf("error opening zm_usb_tx: %d\n", ret);
    }

    ret = port_create("zm_usb_sam", PORT_MODE_UNICAST, &zedmon_usb_sample_port);
    if (ret != NO_ERROR) {
        printf("error creating zm_usb_sample: %d\n", ret);
    }

    port_t usb_sample_reader;
    ret = port_open("zm_usb_sam", (void *)ZEDMON_PORT_CTX_USB_SAMPLE, &usb_sample_reader);
    if (ret != NO_ERROR) {
        printf("error opening zm_usb_sample: %d\n", ret);
    }

    port_t ports[] = {usb_rx_reader, usb_tx_reader, usb_sample_reader};

    ret = port_group(ports, countof(ports), &zedmon_usb_port_group);

    zedmon_ep = data_ep_addr;

    zedmon_if_descriptor[DATA_IN_EP_ADDR_OFFSET]  = data_ep_addr | 0x80;
    zedmon_if_descriptor[DATA_OUT_EP_ADDR_OFFSET] = data_ep_addr;

    usb_append_interface_lowspeed(zedmon_if_descriptor, sizeof(zedmon_if_descriptor));
    usb_append_interface_highspeed(zedmon_if_descriptor, sizeof(zedmon_if_descriptor));

    usb_register_callback(&zedmon_usb_callback, NULL);

    zedmon_tx_busy = false;
    zedmon_usb_thread = thread_create("zedmon_usb", &zedmon_usb_thread_entry, 0x0,
                                      DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
    thread_detach(zedmon_usb_thread);
    thread_resume(zedmon_usb_thread);
}

#include "stm32f0xx_hal.h"
static void print_epr(int i, uint16_t epr) {
    printf("ep%dr: ea:%d stat_tx:%d dtog_tx:%d ctr_tx:%d ep_kind:%d ep_type:%d\n"
           "       setup:%d stat_rx:%d dtog_rx:%d ctr_rx:%d\n",
           i,
           epr & 0xf,
           (epr >> 4) & 0x3,
           (epr >> 6) & 0x1,
           (epr >> 7) & 0x1,
           (epr >> 8) & 0x1,
           (epr >> 9) & 0x3,
           (epr >> 11) & 0x1,
           (epr >> 12) & 0x3,
           (epr >> 14) & 0x1,
           (epr >> 15) & 0x1);
}

static int cmd_usb_dump(int argc, const cmd_args *argv) {
    print_epr(0, USB->EP0R);
    print_epr(1, USB->EP1R);
    print_epr(2, USB->EP2R);
    print_epr(3, USB->EP3R);
    print_epr(4, USB->EP4R);
    print_epr(5, USB->EP5R);
    print_epr(6, USB->EP6R);
    print_epr(7, USB->EP7R);

    return NO_ERROR;
}

STATIC_COMMAND_START
STATIC_COMMAND("usb_dump", "usb dump", &cmd_usb_dump)
STATIC_COMMAND_END(usb);
