/*
 * Copyright (c) 2023 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "pico.h"
#include "cyw43.h"
#include "hci_transport.h"
#include "hci.h"
#include "pico/btstack_hci_transport_cyw43.h"
#include "pico/btstack_chipset_cyw43.h"

// assert outgoing pre-buffer for cyw43 header is available
#if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE < 4)
#error HCI_OUTGOING_PRE_BUFFER_SIZE not defined or smaller than 4. Please update btstack_config.h
#endif

// assert outgoing packet fragments are word aligned
#if !defined(HCI_ACL_CHUNK_SIZE_ALIGNMENT) || ((HCI_ACL_CHUNK_SIZE_ALIGNMENT & 3) != 0)
#error HCI_ACL_CHUNK_SIZE_ALIGNMENT not defined or not a multiply of 4. Please update btstack_config.h
#endif

#define BT_DEBUG_ENABLED 0
#if BT_DEBUG_ENABLED
#define BT_DEBUG(...) CYW43_PRINTF(__VA_ARGS__)
#else
#define BT_DEBUG(...) (void)0
#endif

// Callback when we have data
static void (*hci_transport_cyw43_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = NULL;

// Incoming packet buffer - cyw43 packet header (incl packet type) + incoming pre buffer + max(acl header + acl payload, event header + event data)
__attribute__((aligned(4)))
static uint8_t hci_packet_with_pre_buffer[4 + HCI_INCOMING_PRE_BUFFER_SIZE + HCI_INCOMING_PACKET_BUFFER_SIZE ];

static btstack_data_source_t transport_data_source;
static bool hci_transport_ready;

// Forward declaration
static void hci_transport_cyw43_process(void);

static void hci_transport_data_source_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) {
    assert(callback_type == DATA_SOURCE_CALLBACK_POLL);
    assert(ds == &transport_data_source);
    (void)callback_type;
    (void)ds;
    hci_transport_cyw43_process();
}

static void hci_transport_cyw43_init(const void *transport_config) {
    UNUSED(transport_config);
}

static int hci_transport_cyw43_open(void) {
    int err = cyw43_bluetooth_hci_init();
    if (err != 0) {
        CYW43_PRINTF("Failed to open cyw43 hci controller: %d\n", err);
        return err;
    }

    // OTP should be set in which case BT gets an address of wifi mac + 1
    // If OTP is not set for some reason BT gets set to 43:43:A2:12:1F:AC.
    // So for safety, set the bluetooth device address here.
    bd_addr_t addr;
    cyw43_hal_get_mac(0, (uint8_t*)&addr);
    addr[BD_ADDR_LEN - 1]++;
    hci_set_chipset(btstack_chipset_cyw43_instance());
    hci_set_bd_addr(addr);

    btstack_run_loop_set_data_source_handler(&transport_data_source, &hci_transport_data_source_process);
    btstack_run_loop_enable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_POLL);
    btstack_run_loop_add_data_source(&transport_data_source);
    hci_transport_ready = true;

    return 0;
}

static int hci_transport_cyw43_close(void) {
    btstack_run_loop_disable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_POLL);
    btstack_run_loop_remove_data_source(&transport_data_source);
    hci_transport_ready = false;

    return 0;
}

static void hci_transport_cyw43_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)) {
    hci_transport_cyw43_packet_handler = handler;
}

static int hci_transport_cyw43_can_send_now(uint8_t packet_type) {
    UNUSED(packet_type);
    return true;
}

static int hci_transport_cyw43_send_packet(uint8_t packet_type, uint8_t *packet, int size) {
    // store packet type before actual data and increase size
    // This relies on HCI_OUTGOING_PRE_BUFFER_SIZE being set
    uint8_t *buffer = &packet[-4];
    uint32_t buffer_size = size + 4;
    buffer[3] = packet_type;

    CYW43_THREAD_ENTER
    int err = cyw43_bluetooth_hci_write(buffer, buffer_size);

    if (err != 0) {
        CYW43_PRINTF("Failed to send cyw43 hci packet: %d\n", err);
        assert(false);
    } else {
        BT_DEBUG("bt sent %lu\n", buffer_size);
        static uint8_t packet_sent_event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0};
        hci_transport_cyw43_packet_handler(HCI_EVENT_PACKET, &packet_sent_event[0], sizeof(packet_sent_event));
    }
    CYW43_THREAD_EXIT
    return err;
}

// configure and return hci transport singleton
static const hci_transport_t hci_transport_cyw43 = {
        /* const char * name; */                                        "CYW43",
        /* void   (*init) (const void *transport_config); */            &hci_transport_cyw43_init,
        /* int    (*open)(void); */                                     &hci_transport_cyw43_open,
        /* int    (*close)(void); */                                    &hci_transport_cyw43_close,
        /* void   (*register_packet_handler)(void (*handler)(...); */   &hci_transport_cyw43_register_packet_handler,
        /* int    (*can_send_packet_now)(uint8_t packet_type); */       &hci_transport_cyw43_can_send_now,
        /* int    (*send_packet)(...); */                               &hci_transport_cyw43_send_packet,
        /* int    (*set_baudrate)(uint32_t baudrate); */                NULL,
        /* void   (*reset_link)(void); */                               NULL,
        /* void   (*set_sco_config)(uint16_t voice_setting, int num_connections); */ NULL,
};

const hci_transport_t *hci_transport_cyw43_instance(void) {
    return &hci_transport_cyw43;
}

// Called to perform bt work from a data source
static void hci_transport_cyw43_process(void) {
    CYW43_THREAD_LOCK_CHECK
    uint32_t len = 0;
    bool has_work;
    do {
        int err = cyw43_bluetooth_hci_read(hci_packet_with_pre_buffer, sizeof(hci_packet_with_pre_buffer), &len);
        BT_DEBUG("bt in len=%lu err=%d\n", len, err);
        if (err == 0 && len > 0) {
            hci_transport_cyw43_packet_handler(hci_packet_with_pre_buffer[3], hci_packet_with_pre_buffer + 4, len - 4);
            has_work = true;
        } else {
            has_work = false;
        }
    } while (has_work);
}

// This is called from cyw43_poll_func.
void cyw43_bluetooth_hci_process(void) {
    if (hci_transport_ready) {
        btstack_run_loop_poll_data_sources_from_irq();
    }
}
