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

#if defined(__APPLE__) && !defined(NOFRAMEWORK)
#include <libximc/ximc.h>
#else
#include <ximc.h>
#endif

// This line includes a c-profile for the "8MT173-25" stage
#include "8MT173-25.h"

device_enumeration_t search_devices(int* device_count)
{
    printf("\nSearching for devices...\n");
    const int probe_flags = ENUMERATE_PROBE | ENUMERATE_NETWORK;
    const char* enumerate_hints = "addr=";
    device_enumeration_t devenum = enumerate_devices(probe_flags, enumerate_hints);
    if (!devenum) {
        printf("Error searching for devices\n");
        *device_count = 0;
        return devenum;
    }

    *device_count = get_device_count(devenum);
    if (*device_count < 1) {
        printf("No devices found\n");
        return devenum;
    }

    printf("Found %d devices\n", *device_count + 1);
    return devenum;
}

void print_device_list(device_enumeration_t devenum, int device_count)
{
    printf("\nFound devices list:\n");
    int i = 0;
    for (i = 0; i < device_count; ++i) {
        printf(" #%d. %s\n", i + 1, get_device_name(devenum, i));
    }
    printf(" #%d. virtual\n", i + 1);
}

char* create_virtual_device_name()
{
    static char device_name[256];
    static char path[255];

#if defined(_WIN32) || defined(_WIN64)
    strcpy(path, getenv("USERPROFILE"));
    strcat(path, "\\virt_controller.bin");
    strcpy(device_name, "xi-emu:///");
    strcat(device_name, path);
#else
    strcpy(path, getenv("HOME"));
    strcat(path, "/virt_controller.bin");
    strcpy(device_name, "xi-emu:///");
    strcat(device_name, path);
#endif
    printf("Virtual controller file path: '%s'\n", path);

    return device_name;
}

char* get_device_name_from_list(device_enumeration_t devenum, int device_count)
{
    char buffer[256];
    static char device_name[256];
    while (1) {
        print_device_list(devenum, device_count);
        printf("When using an Ethernet (TCP protocol) connection, multi-user interaction with the device is possible. In this case, the same device may be controlled simultaneously from multiple sources, which can potentially lead to control conflicts.\nEnter device number from the list:\n");
        fgets(buffer, sizeof(buffer), stdin);
        int number;
        if (sscanf(buffer, "%d", &number) != 1) {
            continue;
        }

        if (1 <= number && number <= device_count) {
            char* name = get_device_name(devenum, number - 1);
            strcpy(device_name, name);
            printf("Selected device: '%s'\n", device_name);
            return device_name;
        }

        if (number == device_count + 1) {
            return create_virtual_device_name();
        }
    }
}

char* choose_device()
{
    int device_count = 0;
    device_enumeration_t devenum = search_devices(&device_count);
    char* device_name;
    if (device_count < 1) {
        printf("The real controller is not found or busy with another app.\nThe virtual controller is opening to check the operation of the library...\n");
        device_name = create_virtual_device_name();
    }
    else {
        device_name = get_device_name_from_list(devenum, device_count);
    }
    free_enumerate_devices(devenum);
    return device_name;
}

int warn_user_about_modifications()
{
    char buffer[256];
    while (1) {
        printf("\nThe script will modify all controller settings. Continue? [y/n]:\n");
        fgets(buffer, sizeof(buffer), stdin);
        char answer;
        if (sscanf(buffer, "%c", &answer) == 1) {
            if (answer == 'y' || answer == 'Y') {
                return 0;
            }

            if (answer == 'n' || answer == 'N') {
                return 1;
            }
        }
    }
}

int main(int argc, char* argv[])
{	
    char ximc_version_str[32];
    ximc_version(ximc_version_str);
    printf("This is a ximc test program\nlibximc version %s\n", ximc_version_str);

    if (warn_user_about_modifications()) {
        return 0;
    }

    char* device_name = choose_device();
    printf("\nOpening device...");
    device_t device = open_device(device_name);
    if (device == device_undefined) {
        printf("\nError opening device\nPress Enter to exit...");
        char terminating_str[2];
        fgets(terminating_str, 2, stdin);
        return 1;
    }
    printf(" Done\n");

    printf("Setting profile for 8MT173-25...");
    result_t result = set_profile_8MT173_25(device);
    printf(" Done. Result: %d\n", result);

    printf("Closing device...");
    close_device(&device);
    printf(" Done\n");

    printf("Press Enter to exit...");
    char terminating_str[2];
    fgets(terminating_str, 2, stdin);
    return 0;
}
