#include "ltr/include/ltrapi.h"
#include <stdio.h>
#include <string.h>

#ifdef _WIN32
#include <locale.h>
#include <conio.h>
#else
#include <signal.h>
#include <unistd.h>
#endif

static int f_out = 0;

#ifndef _WIN32
/* Обработчик сигнала завершения для Linux */
static void f_abort_handler(int sig) {
    f_out = 1;
}
#endif

typedef struct {
    const char *serial;
    DWORD addr;
} t_open_param;

/* Разбор параметров командной строки. Если указано меньше, то используются
 * значения по умолчанию:
 * 1 параметр - серийный номер крейта
 * 2 параметр - ip-адрес сервера */
static int f_get_params(int argc, char** argv, t_open_param* par) {
    int err = 0;
    par->serial = "";
    par->addr = LTRD_ADDR_DEFAULT;

    if (argc > 1)
        par->serial = argv[1];
    if (argc > 2) {
        int a[4],i;
        if (sscanf(argv[2], "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3])!=4) {
            fprintf(stderr, "Неверный формат IP-адреса!!\n");
            err = -1;
        }

        for (i=0; (i < 4) && !err; i++) {
            if ((a[i]<0) || (a[i] > 255)) {
                fprintf(stderr, "Недействительный IP-адрес!!\n");
                err = -1;
            }
        }

        if (!err) {
            par->addr = (a[0] << 24) | (a[1]<<16) | (a[2]<<8) | a[3];
        }
    }
    return err;
}


int main(int argc, char **argv) {
    INT err;
    t_open_param par;
    int cntr = 0;
#ifndef _WIN32
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    /* В ОС Linux устанавливаем свой обработчик на сигнал закрытия,
       чтобы завершить сбор корректно */
    sa.sa_handler = f_abort_handler;
    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGABRT, &sa, NULL);
#endif

#ifdef _WIN32
    /* для вывода русских букв в консоль для ОС Windows*/
    setlocale(LC_ALL, "");
#endif

    err = f_get_params(argc, argv, &par);

    if (!err) {
        if (err==LTR_OK) {
            printf("Тест запущен. Для останова нажмите %s\n",
#ifdef _WIN32
                   "любую клавишу"
#else
                   "CTRL+C"
#endif
                   );
            fflush(stdout);
        }
    }



    while ((err==LTR_OK) && !f_out) {
        TLTR hcrate;
        LTR_Init(&hcrate);
        err = LTR_OpenCrate(&hcrate, par.addr, LTRD_PORT_DEFAULT, LTR_CRATE_IFACE_UNKNOWN, par.serial);
        if (err!=LTR_OK) {
            fprintf(stderr, "\nНевозможно установить связь с крейтом! Ошибка %d: %s\n",
                    err, LTR_GetErrorString(err));
        } else {
            TLTR_CONFIG cfg;
            unsigned int i;

            cfg.digout[0] = LTR_DIGOUT_START;
            cfg.digout[1] = LTR_DIGOUT_SECOND;
            for (i=0; i < sizeof(cfg.userio)/sizeof(cfg.userio[0]); i++)
               cfg.userio[i] = LTR_USERIO_DEFAULT;
            cfg.digout_en = 1;

            err = LTR_Config(&hcrate, &cfg);
            if (err!=LTR_OK) {
                fprintf(stderr, "\nНе удалось сконфигурировать крейт! Ошибка %d: %s\n",
                          err, LTR_GetErrorString(err));
            }
            LTR_Close(&hcrate);


            if (err==LTR_OK) {
                cntr++;
                LTRAPI_SLEEP_MS(100);
                if ((cntr % 0x3) == 0) {
                    printf(".");
                    fflush(stdout);
                }
#ifdef _WIN32
                /* проверка нажатия клавиши для выхода */
                if (_kbhit())
                   f_out = 1;
#endif
            }

       }
    }

    printf("\nТест завершен %s. Удачных циклов %d\n", err==LTR_OK ? "успешно" : "с ошибкой", cntr);
    return -err;
}
