#include <windows.h>
#include <stdio.h>
#include "hdlc/client.h"
#include "stdint.h"
#include "stdbool.h"
#include "protocol/protocol.h"

int main() {
    struct Client hdlc;
    HANDLE Port_1;
    HANDLE Port_2;
    init_hdlc_client(&hdlc, 200);

    hdlc_connect(&hdlc);
    uint8_t buffer_send_connect[10];

    hdlc_get_raw_frame(&hdlc, buffer_send_connect, sizeof buffer_send_connect);

    // Открыть COM-порт
    Port_1 = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE,
                      0, NULL, OPEN_EXISTING,
                      0, NULL);

    if (Port_1 == INVALID_HANDLE_VALUE) {
        DWORD errorCode = GetLastError();
        //printf("Create file err: %d.\n", INVALID_HANDLE_VALUE);
        printf("Create file err: %lu.\n", errorCode);
        return 1;
    }

    COMMTIMEOUTS timeouts1 = {0};
    // Установка таймаутов чтения/записи
    timeouts1.ReadIntervalTimeout = 100;
    timeouts1.ReadTotalTimeoutConstant = 100;
    timeouts1.ReadTotalTimeoutMultiplier = 20;
    timeouts1.WriteTotalTimeoutConstant = 50;
    timeouts1.WriteTotalTimeoutMultiplier = 20;

    if (!SetCommTimeouts(Port_1, &timeouts1)) {
        printf("Ошибка при установке таймаутов COM-порта.\n");
        CloseHandle(Port_1);
        return 1;
    }

    // Открыть COM-порт
    Port_2 = CreateFile("COM2", GENERIC_READ | GENERIC_WRITE,
                        0, NULL, OPEN_EXISTING,
                        0, NULL);

    if (Port_2 == INVALID_HANDLE_VALUE) {
        DWORD errorCode = GetLastError();
        //printf("Create file err: %d.\n", INVALID_HANDLE_VALUE);
        printf("Create file err: %lu.\n", errorCode);
        return 1;
    }

    if (!SetCommTimeouts(Port_2, &timeouts1)) {
        printf("Ошибка при установке таймаутов COM-порта.\n");
        CloseHandle(Port_1);
        return 1;
    }

    //Write frame from port 1
    DWORD written;
    BOOL success_write_send = WriteFile(Port_1, buffer_send_connect, sizeof buffer_send_connect,
                             &written, NULL);

    if (!success_write_send){
        DWORD errorCode = GetLastError();
        printf("WriteFile err: %lu.\n", errorCode);
        return -1;
    }
    if (written != sizeof buffer_send_connect){
        printf("Failed to write all bytes to port");
        return -1;
    }

    bool flag_connection = false;
    while(!flag_connection){
        uint8_t buffer_recive_connect[10];
        DWORD received;
        BOOL success = ReadFile(Port_2, buffer_recive_connect, sizeof buffer_recive_connect,
                                &received, NULL);
        if (!success)
        {
            printf("Failed to read from port");
            return -1;
        }

        int err = hdlc_decode_recived_raw_data(&hdlc, buffer_recive_connect, sizeof buffer_recive_connect,
                                           0, 0);
        if (err < 0){
//            if (err == ERR_INVALID_SEQ_NUMBER_FRAME){
//                uint8_t* buffer_rej[10];
//                hdlc_get_raw_frame(&hdlc, buffer_rej, sizeof buffer_rej);
//                //UART_send(buffer_rej, sizeof buffer_rej);
//                return err;
//            }
            return err;
        }

        if (hdlc.state == READY_STATE){
            flag_connection = true;
        }
    }

    struct message mess;
    mess.numbers[0] = 12133.23;
    mess.numbers[1] = 21232.1;
    mess.numbers[2] = 100;
    mess.len_numbers = 3;
    mess.str = "word war";
    mess.len_str = sizeof mess.str;

    uint8_t data[32];
    size_t len_data;
    protocol_encode(mess, data, &len_data);

    hdlc_send_data(&hdlc, data, len_data);
    uint8_t buffer_data[72];
    hdlc_get_raw_frame(&hdlc, buffer_data, sizeof buffer_data);

    DWORD written_data;
    BOOL success_write_data = WriteFile(Port_1, buffer_send_connect, sizeof buffer_send_connect,
                                        &written_data, NULL);

    if (!success_write_data){
        DWORD errorCode = GetLastError();
        printf("WriteFile err: %lu.\n", errorCode);
        return -1;
    }
    if (written_data != sizeof buffer_send_connect){
        printf("Failed to write all bytes to port");
        return -1;
    }

    for (int i = 0; i <1100; i++ ){

    }

    bool flag_data = false;
    while(!flag_data){
        uint8_t buffer_recive_data[80];
        DWORD received_data;
        BOOL success = ReadFile(Port_2, &buffer_recive_data, sizeof buffer_recive_data,
                                &received_data, NULL);
        if (!success)
        {
            printf("Failed to read from port");
            return -1;
        }

        uint8_t data_recive[64];
        size_t len_data_recive;
        int err = hdlc_decode_recived_raw_data(&hdlc, buffer_recive_data, sizeof buffer_recive_data,
                                               data_recive, &len_data_recive);
        if (err < 0){
//            if (err == ERR_INVALID_SEQ_NUMBER_FRAME){
//                uint8_t* buffer_rej[10];
//                hdlc_get_raw_frame(&hdlc, buffer_rej, sizeof buffer_rej);
//                //UART_send(buffer_rej, sizeof buffer_rej);
//                return err;
//            }
            return err;
        }
        for(int i = 0; i < sizeof data_recive; i++){
            printf("%d: %d\n", i, data_recive[i]);
        }

        struct message resp;
        protocol_decode(data_recive, sizeof data_recive, &resp);
        if (resp.len_str > 0){
            printf("1: %f\n", resp.numbers[0]);
            printf("2: %f\n", resp.numbers[1]);
            printf("3: %f\n", resp.numbers[2]);
            printf("str: %s\n", resp.str);
            flag_data = true;
        }
    }

    CloseHandle(Port_1);
    CloseHandle(Port_2);

    return 0;
}