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

#include <string.h>
#include <stdio.h>
#include <stdarg.h>

#include "pico.h"
#include "pico/mutex.h"
#include "pico/printf.h"
#include "pico/stdio.h"
#include "pico/stdio/driver.h"
#include "pico/time.h"

#if LIB_PICO_STDIO_UART
#include "pico/stdio_uart.h"
#endif

#if LIB_PICO_STDIO_USB
#include "pico/stdio_usb.h"
#endif

#if LIB_PICO_STDIO_SEMIHOSTING
#include "pico/stdio_semihosting.h"
#endif

static stdio_driver_t *drivers;
static stdio_driver_t *filter;

#if PICO_STDOUT_MUTEX
auto_init_mutex(print_mutex);

bool stdout_serialize_begin(void) {
    lock_owner_id_t caller = lock_get_caller_owner_id();
    // not using lock_owner_id_t to avoid backwards incompatibility change to mutex_try_enter API
    static_assert(sizeof(lock_owner_id_t) <= 4, "");
    uint32_t owner;
    if (!mutex_try_enter(&print_mutex, &owner)) {
        if (owner == (uint32_t)caller) {
            return false;
        }
        // we are not a nested call, so lets wait
        mutex_enter_blocking(&print_mutex);
    }
    return true;
}

void stdout_serialize_end(void) {
    mutex_exit(&print_mutex);
}

#else
static bool print_serialize_begin(void) {
    return true;
}
static void print_serialize_end(void) {
}
#endif

static void stdio_out_chars_crlf(stdio_driver_t *driver, const char *s, int len) {
#if PICO_STDIO_ENABLE_CRLF_SUPPORT
    if (!driver->crlf_enabled) {
        driver->out_chars(s, len);
        return;
    }
    int first_of_chunk = 0;
    static const char crlf_str[] = {'\r', '\n'};
    for (int i = 0; i < len; i++) {
        bool prev_char_was_cr = i > 0 ? s[i - 1] == '\r' : driver->last_ended_with_cr;
        if (s[i] == '\n' && !prev_char_was_cr) {
            if (i > first_of_chunk) {
                driver->out_chars(&s[first_of_chunk], i - first_of_chunk);
            }
            driver->out_chars(crlf_str, 2);
            first_of_chunk = i + 1;
        }
    }
    if (first_of_chunk < len) {
        driver->out_chars(&s[first_of_chunk], len - first_of_chunk);
    }
    if (len > 0) {
        driver->last_ended_with_cr = s[len - 1] == '\r';
    }
#else
    driver->out_chars(s, len);
#endif
}

static bool stdio_put_string(const char *s, int len, bool newline) {
    bool serialized = stdout_serialize_begin();
    if (!serialized) {
#if PICO_STDIO_IGNORE_NESTED_STDOUT
        return false;
#endif
    }
    if (len == -1) len = (int)strlen(s);
    for (stdio_driver_t *driver = drivers; driver; driver = driver->next) {
        if (!driver->out_chars) continue;
        if (filter && filter != driver) continue;
        stdio_out_chars_crlf(driver, s, len);
        if (newline) {
            const char c = '\n';
            stdio_out_chars_crlf(driver, &c, 1);
        }
    }
    if (serialized) {
        stdout_serialize_end();
    }
    return len;
}

static int stdio_get_until(char *buf, int len, absolute_time_t until) {
    do {
        // todo round robin might be nice on each call, but then again hopefully
        //  no source will starve the others
        for (stdio_driver_t *driver = drivers; driver; driver = driver->next) {
            if (filter && filter != driver) continue;
            if (driver->in_chars) {
                int read = driver->in_chars(buf, len);
                if (read > 0) {
                    return read;
                }
            }
        }
        // we sleep here in case the in_chars methods acquire mutexes or disable IRQs and
        // potentially starve out what they are waiting on (have seen this with USB)
        busy_wait_us(1);
    } while (!time_reached(until));
    return PICO_ERROR_TIMEOUT;
}

int WRAPPER_FUNC(putchar)(int c) {
    char cc = (char)c;
    stdio_put_string(&cc, 1, false);
    return c;
}

int WRAPPER_FUNC(puts)(const char *s) {
    int len = (int)strlen(s);
    stdio_put_string(s, len, true);
    stdio_flush();
    return len;
}

int _read(int handle, char *buffer, int length) {
    if (handle == 0) {
        return stdio_get_until(buffer, length, at_the_end_of_time);
    }
    return -1;
}

int _write(int handle, char *buffer, int length) {
    if (handle == 1) {
        stdio_put_string(buffer, length, false);
        return length;
    }
    return -1;
}

void stdio_set_driver_enabled(stdio_driver_t *driver, bool enable) {
    stdio_driver_t *prev = drivers;
    for (stdio_driver_t *d = drivers; d; d = d->next) {
        if (d == driver) {
            if (!enable) {
                prev->next = d->next;
                driver->next = NULL;
            }
            return;
        }
        prev = d;
    }
    if (enable) {
        if (prev) prev->next = driver;
        else drivers = driver;
    }
}

void stdio_flush() {
    for (stdio_driver_t *d = drivers; d; d = d->next) {
        if (d->out_flush) d->out_flush();
    }
}

typedef struct stdio_stack_buffer {
    int used;
    char buf[PICO_STDIO_STACK_BUFFER_SIZE];
} stdio_stack_buffer_t;

static void stdio_stack_buffer_flush(stdio_stack_buffer_t *buffer) {
    if (buffer->used) {
        for (stdio_driver_t *d = drivers; d; d = d->next) {
            if (!d->out_chars) continue;
            if (filter && filter != d) continue;
            stdio_out_chars_crlf(d, buffer->buf, buffer->used);
        }
        buffer->used = 0;
    }
}

static void stdio_buffered_printer(char c, void *arg) {
    stdio_stack_buffer_t *buffer = (stdio_stack_buffer_t *)arg;
    if (buffer->used == PICO_STDIO_STACK_BUFFER_SIZE) {
        stdio_stack_buffer_flush(buffer);
    }
    buffer->buf[buffer->used++] = c;
}

int WRAPPER_FUNC(vprintf)(const char *format, va_list va) {
    bool serialzed = stdout_serialize_begin();
    if (!serialzed) {
#if PICO_STDIO_IGNORE_NESTED_STDOUT
        return 0;
#endif
    }
    int ret;
#if LIB_PICO_PRINTF_PICO
    struct stdio_stack_buffer buffer = {.used = 0};
    ret = vfctprintf(stdio_buffered_printer, &buffer, format, va);
    stdio_stack_buffer_flush(&buffer);
    stdio_flush();
#elif LIB_PICO_PRINTF_NONE
    extern void printf_none_assert();
    printf_none_assert();
#else
    extern int REAL_FUNC(vprintf)(const char *format, va_list va);
    ret = REAL_FUNC(vprintf)(format, va);
#endif
    if (serialzed) {
        stdout_serialize_end();
    }
    return ret;
}

int __printflike(1, 0) WRAPPER_FUNC(printf)(const char* format, ...)
{
    va_list va;
    va_start(va, format);
    int ret = vprintf(format, va);
    va_end(va);
    return ret;
}

void stdio_init_all() {
    // todo add explicit custom, or registered although you can call stdio_enable_driver explicitly anyway
    // These are well known ones
#if LIB_PICO_STDIO_UART
    stdio_uart_init();
#endif

#if LIB_PICO_STDIO_SEMIHOSTING
    stdio_semihosting_init();
#endif

#if LIB_PICO_STDIO_USB
    stdio_usb_init();
#endif
}

int WRAPPER_FUNC(getchar)(void) {
    char buf[1];
    int len = stdio_get_until(buf, 1, at_the_end_of_time);
    if (len < 0) return len;
    assert(len == 1);
    return (uint8_t)buf[0];
}

int getchar_timeout_us(uint32_t timeout_us) {
    char buf[1];
    int rc = stdio_get_until(buf, sizeof(buf), make_timeout_time_us(timeout_us));
    if (rc < 0) return rc;
    assert(rc);
    return (uint8_t)buf[0];
}

void stdio_filter_driver(stdio_driver_t *driver) {
    filter = driver;
}

void stdio_set_translate_crlf(stdio_driver_t *driver, bool enabled) {
#if PICO_STDIO_ENABLE_CRLF_SUPPORT
    if (enabled && !driver->crlf_enabled) {
        driver->last_ended_with_cr = false;
    }
    driver->crlf_enabled = enabled;
#else
    panic_unsupported();
#endif
}
