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

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

#include "pico/unique_id.h"
#include "cyw43.h"
#include "pico/cyw43_arch.h"
#include "cyw43_ll.h"
#include "cyw43_stats.h"

#if PICO_CYW43_ARCH_DEBUG_ENABLED
#define CYW43_ARCH_DEBUG(...) printf(__VA_ARGS__)
#else
#define CYW43_ARCH_DEBUG(...) ((void)0)
#endif

static uint32_t country_code = PICO_CYW43_ARCH_DEFAULT_COUNTRY_CODE;

static async_context_t *async_context;

void cyw43_arch_set_async_context(async_context_t *context) {
    async_context = context;
}

void cyw43_arch_enable_sta_mode(void) {
    assert(cyw43_is_initialized(&cyw43_state));
    cyw43_wifi_set_up(&cyw43_state, CYW43_ITF_STA, true, cyw43_arch_get_country_code());
}

void cyw43_arch_disable_sta_mode(void) {
    assert(cyw43_is_initialized(&cyw43_state));
    if (cyw43_state.itf_state & (1 << CYW43_ITF_STA)) {
        cyw43_cb_tcpip_deinit(&cyw43_state, CYW43_ITF_STA);
        cyw43_state.itf_state &= ~(1 << CYW43_ITF_STA);
    }
    if (cyw43_state.wifi_join_state) {
        cyw43_wifi_leave(&cyw43_state, CYW43_ITF_STA);
    }
}

void cyw43_arch_enable_ap_mode(const char *ssid, const char *password, uint32_t auth) {
    assert(cyw43_is_initialized(&cyw43_state));
    cyw43_wifi_ap_set_ssid(&cyw43_state, strlen(ssid), (const uint8_t *) ssid);
    if (password) {
        cyw43_wifi_ap_set_password(&cyw43_state, strlen(password), (const uint8_t *) password);
        cyw43_wifi_ap_set_auth(&cyw43_state, auth);
    } else {
        cyw43_wifi_ap_set_auth(&cyw43_state, CYW43_AUTH_OPEN);
    }
    cyw43_wifi_set_up(&cyw43_state, CYW43_ITF_AP, true, cyw43_arch_get_country_code());
}

void cyw43_arch_disable_ap_mode(void) {
    assert(cyw43_is_initialized(&cyw43_state));
    cyw43_wifi_set_up(&cyw43_state, CYW43_ITF_AP, false, cyw43_arch_get_country_code());
    cyw43_state.itf_state &= ~(1 << CYW43_ITF_AP);
}

#if PICO_CYW43_ARCH_DEBUG_ENABLED
// Return a string for the wireless state
static const char* cyw43_tcpip_link_status_name(int status)
{
    switch (status) {
    case CYW43_LINK_DOWN:
        return "link down";
    case CYW43_LINK_JOIN:
        return "joining";
    case CYW43_LINK_NOIP:
        return "no ip";
    case CYW43_LINK_UP:
        return "link up";
    case CYW43_LINK_FAIL:
        return "link fail";
    case CYW43_LINK_NONET:
        return "network fail";
    case CYW43_LINK_BADAUTH:
        return "bad auth";
    }
    return "unknown";
}
#endif


int cyw43_arch_wifi_connect_bssid_async(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth) {
    if (!pw) auth = CYW43_AUTH_OPEN;
    // Connect to wireless
    return cyw43_wifi_join(&cyw43_state, strlen(ssid), (const uint8_t *)ssid, pw ? strlen(pw) : 0, (const uint8_t *)pw, auth, bssid, CYW43_CHANNEL_NONE);
}

int cyw43_arch_wifi_connect_async(const char *ssid, const char *pw, uint32_t auth) {
    return cyw43_arch_wifi_connect_bssid_async(ssid, NULL, pw, auth);
}

static int cyw43_arch_wifi_connect_bssid_until(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth, absolute_time_t until) {
    int err = cyw43_arch_wifi_connect_bssid_async(ssid, bssid, pw, auth);
    if (err) return err;

    int status = CYW43_LINK_UP + 1;
    while(status >= 0 && status != CYW43_LINK_UP) {
        int new_status = cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA);
        // If there was no network, keep trying
        if (new_status == CYW43_LINK_NONET) {
            new_status = CYW43_LINK_JOIN;
            err = cyw43_arch_wifi_connect_bssid_async(ssid, bssid, pw, auth);
            if (err) return err;
        }
        if (new_status != status) {
            status = new_status;
            CYW43_ARCH_DEBUG("connect status: %s\n", cyw43_tcpip_link_status_name(status));
        }
        if (time_reached(until)) {
            return PICO_ERROR_TIMEOUT;
        }
        // Do polling
        cyw43_arch_poll();
        cyw43_arch_wait_for_work_until(until);
    }
    // Turn status into a pico_error_codes, CYW43_LINK_NONET shouldn't happen as we fail with PICO_ERROR_TIMEOUT instead
    assert(status == CYW43_LINK_UP || status == CYW43_LINK_BADAUTH || status == CYW43_LINK_FAIL);
    if (status == CYW43_LINK_UP) {
        return PICO_OK; // success
    } else if (status == CYW43_LINK_BADAUTH) {
        return PICO_ERROR_BADAUTH;
    } else {
        return PICO_ERROR_CONNECT_FAILED;
    }
}

// Connect to wireless, return with success when an IP address has been assigned
static int cyw43_arch_wifi_connect_until(const char *ssid, const char *pw, uint32_t auth, absolute_time_t until) {
    return cyw43_arch_wifi_connect_bssid_until(ssid, NULL, pw, auth, until);
}

int cyw43_arch_wifi_connect_blocking(const char *ssid, const char *pw, uint32_t auth) {
    return cyw43_arch_wifi_connect_until(ssid, pw, auth, at_the_end_of_time);
}

int cyw43_arch_wifi_connect_bssid_blocking(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth) {
    return cyw43_arch_wifi_connect_bssid_until(ssid, bssid, pw, auth, at_the_end_of_time);
}

int cyw43_arch_wifi_connect_timeout_ms(const char *ssid, const char *pw, uint32_t auth, uint32_t timeout_ms) {
    return cyw43_arch_wifi_connect_until(ssid, pw, auth, make_timeout_time_ms(timeout_ms));
}

int cyw43_arch_wifi_connect_bssid_timeout_ms(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth, uint32_t timeout_ms) {
    return cyw43_arch_wifi_connect_bssid_until(ssid, bssid, pw, auth, make_timeout_time_ms(timeout_ms));
}

uint32_t cyw43_arch_get_country_code(void) {
    return country_code;
}

int cyw43_arch_init_with_country(uint32_t country) {
    country_code = country;
    return cyw43_arch_init();
}

void cyw43_arch_gpio_put(uint wl_gpio, bool value) {
    invalid_params_if(CYW43_ARCH, wl_gpio >= CYW43_WL_GPIO_COUNT);
    cyw43_gpio_set(&cyw43_state, (int)wl_gpio, value);
}

bool cyw43_arch_gpio_get(uint wl_gpio) {
    invalid_params_if(CYW43_ARCH, wl_gpio >= CYW43_WL_GPIO_COUNT);
    bool value = false;
    cyw43_gpio_get(&cyw43_state, (int)wl_gpio, &value);
    return value;
}

async_context_t *cyw43_arch_async_context(void) {
    return async_context;
}

void cyw43_arch_poll(void)
{
    async_context_poll(async_context);
}

void cyw43_arch_wait_for_work_until(absolute_time_t until) {
    async_context_wait_for_work_until(async_context, until);
}
