#include "uart_driver.h"
#include <unity.h>

void setUp(void) {
    // Set up test fixtures before each test
}

void tearDown(void) {
    // Clean up test fixtures after each test
}

void test_uart_driver_init_valid_config(void) {
    uart_driver_t driver;
    uart_config_t config = {
        .tx_pin = 17,
        .rx_pin = 18,
        .baud_rate = 9600,
        .data_bits = 8,
        .parity = 0, // none
        .stop_bits = 1
    };

    TEST_ASSERT_TRUE(uart_driver_init(&driver, &config));
    TEST_ASSERT_TRUE(uart_driver_is_initialized(&driver));

    uart_driver_deinit(&driver);
}

void test_uart_driver_init_invalid_baud_rate(void) {
    uart_driver_t driver;
    uart_config_t config = {
        .tx_pin = 17,
        .rx_pin = 18,
        .baud_rate = 0, // Invalid baud rate
        .data_bits = 8,
        .parity = 0,
        .stop_bits = 1
    };

    TEST_ASSERT_FALSE(uart_driver_init(&driver, &config));
    TEST_ASSERT_FALSE(uart_driver_is_initialized(&driver));
}

void test_uart_driver_init_invalid_data_bits(void) {
    uart_driver_t driver;
    uart_config_t config = {
        .tx_pin = 17,
        .rx_pin = 18,
        .baud_rate = 9600,
        .data_bits = 9, // Invalid data bits
        .parity = 0,
        .stop_bits = 1
    };

    TEST_ASSERT_FALSE(uart_driver_init(&driver, &config));
    TEST_ASSERT_FALSE(uart_driver_is_initialized(&driver));
}

void test_uart_driver_init_null_pointers(void) {
    uart_driver_t driver;
    uart_config_t config = {
        .tx_pin = 17,
        .rx_pin = 18,
        .baud_rate = 9600,
        .data_bits = 8,
        .parity = 0,
        .stop_bits = 1
    };

    // Test NULL driver pointer
    TEST_ASSERT_FALSE(uart_driver_init(NULL, &config));

    // Test NULL config pointer
    TEST_ASSERT_FALSE(uart_driver_init(&driver, NULL));
}

void test_uart_driver_send_receive(void) {
    uart_driver_t driver;
    uart_config_t config = {
        .tx_pin = 17,
        .rx_pin = 18,
        .baud_rate = 9600,
        .data_bits = 8,
        .parity = 0,
        .stop_bits = 1
    };

    TEST_ASSERT_TRUE(uart_driver_init(&driver, &config));
    TEST_ASSERT_TRUE(uart_driver_is_initialized(&driver));

    uint8_t test_data[] = {0x01, 0x02, 0x03, 0x04, 0x05};
    size_t test_length = sizeof(test_data);

    // Test sending data
    TEST_ASSERT_TRUE(uart_driver_send(&driver, test_data, test_length, 1000));

    // Test receiving data (should return 0 in our mock implementation)
    uint8_t rx_buffer[10];
    int bytes_received = uart_driver_receive(&driver, rx_buffer, sizeof(rx_buffer), 100);
    TEST_ASSERT_EQUAL_INT(0, bytes_received); // Our mock returns 0 (no data)

    uart_driver_deinit(&driver);
}

void test_uart_driver_send_null_data(void) {
    uart_driver_t driver;
    uart_config_t config = {
        .tx_pin = 17,
        .rx_pin = 18,
        .baud_rate = 9600,
        .data_bits = 8,
        .parity = 0,
        .stop_bits = 1
    };

    TEST_ASSERT_TRUE(uart_driver_init(&driver, &config));

    // Test sending NULL data
    TEST_ASSERT_FALSE(uart_driver_send(&driver, NULL, 5, 1000));

    uart_driver_deinit(&driver);
}

void test_uart_driver_receive_null_buffer(void) {
    uart_driver_t driver;
    uart_config_t config = {
        .tx_pin = 17,
        .rx_pin = 18,
        .baud_rate = 9600,
        .data_bits = 8,
        .parity = 0,
        .stop_bits = 1
    };

    TEST_ASSERT_TRUE(uart_driver_init(&driver, &config));

    // Test receiving with NULL buffer
    TEST_ASSERT_EQUAL_INT(-1, uart_driver_receive(&driver, NULL, 10, 100));

    uart_driver_deinit(&driver);
}

void test_uart_driver_uninitialized_operations(void) {
    uart_driver_t driver = {0}; // Not initialized
    uint8_t test_data = 0x01;
    uint8_t rx_buffer[10];

    // Test operations on uninitialized driver
    TEST_ASSERT_FALSE(uart_driver_send(&driver, &test_data, 1, 1000));
    TEST_ASSERT_EQUAL_INT(-1, uart_driver_receive(&driver, rx_buffer, sizeof(rx_buffer), 100));
    TEST_ASSERT_FALSE(uart_driver_is_initialized(&driver));
}

void test_uart_driver_deinit(void) {
    uart_driver_t driver;
    uart_config_t config = {
        .tx_pin = 17,
        .rx_pin = 18,
        .baud_rate = 9600,
        .data_bits = 8,
        .parity = 0,
        .stop_bits = 1
    };

    TEST_ASSERT_TRUE(uart_driver_init(&driver, &config));
    TEST_ASSERT_TRUE(uart_driver_is_initialized(&driver));

    uart_driver_deinit(&driver);
    TEST_ASSERT_FALSE(uart_driver_is_initialized(&driver));
}

int main(void) {
    UNITY_BEGIN();

    RUN_TEST(test_uart_driver_init_valid_config);
    RUN_TEST(test_uart_driver_init_invalid_baud_rate);
    RUN_TEST(test_uart_driver_init_invalid_data_bits);
    RUN_TEST(test_uart_driver_init_null_pointers);
    RUN_TEST(test_uart_driver_send_receive);
    RUN_TEST(test_uart_driver_send_null_data);
    RUN_TEST(test_uart_driver_receive_null_buffer);
    RUN_TEST(test_uart_driver_uninitialized_operations);
    RUN_TEST(test_uart_driver_deinit);

    return UNITY_END();
}