#include "usb_cdc_log.h"

#include <stdio.h>

#include "esp_check.h"
#include "esp_log.h"
#include "tinyusb.h"
#include "tusb_cdc_acm.h"

static const char *TAG = "usb_log";

static bool s_initialized;
static bool s_host_ready;

static void usb_cdc_line_state_changed_callback(int itf, cdcacm_event_t *event)
{
    (void)itf;
    s_host_ready = event->line_state_changed_data.dtr;
    if (s_host_ready) {
        const char banner[] = "\r\nwatch-watch log over USB CDC\r\n";
        tinyusb_cdcacm_write_queue(TINYUSB_CDC_ACM_0, (const uint8_t *)banner, sizeof(banner) - 1);
        tinyusb_cdcacm_write_flush(TINYUSB_CDC_ACM_0, 0);
    }
}

bool usb_cdc_log_ready(void)
{
    return s_host_ready;
}

esp_err_t usb_cdc_log_init(void)
{
    if (s_initialized) {
        return ESP_OK;
    }

    const tinyusb_config_t tusb_cfg = {
        .device_descriptor = NULL,
        .string_descriptor = NULL,
        .external_phy = false,
#if (TUD_OPT_HIGH_SPEED)
        .fs_configuration_descriptor = NULL,
        .hs_configuration_descriptor = NULL,
        .qualifier_descriptor = NULL,
#else
        .configuration_descriptor = NULL,
#endif
    };

    ESP_RETURN_ON_ERROR(tinyusb_driver_install(&tusb_cfg), TAG, "TinyUSB init failed");

    const tinyusb_config_cdcacm_t acm_cfg = {
        .usb_dev = TINYUSB_USBDEV_0,
        .cdc_port = TINYUSB_CDC_ACM_0,
        .rx_unread_buf_sz = 64,
        .callback_rx = NULL,
        .callback_rx_wanted_char = NULL,
        .callback_line_state_changed = usb_cdc_line_state_changed_callback,
        .callback_line_coding_changed = NULL,
    };
    ESP_RETURN_ON_ERROR(tusb_cdc_acm_init(&acm_cfg), TAG, "CDC init failed");

    s_initialized = true;
    ESP_LOGI(TAG, "USB CDC лог ініціалізовано (перенаправлення ESP_LOG вимкнено)");
    return ESP_OK;
}
