/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */

#include <open62541/client_config_default.h>
#include <open62541/client_highlevel.h>
#include <open62541/client_subscriptions.h>
#include <open62541/plugin/log_stdout.h>

#include <stdlib.h>

int main(int argc, char *argv[])
{
    UA_Client *client = UA_Client_new();
    UA_ClientConfig_setDefault(UA_Client_getConfig(client));
    char *url = argv[1];
    int ns = atoi(argv[2]);
    char *node_path = argv[3];

    /* Listing endpoints */
    UA_EndpointDescription *endpointArray = NULL;
    size_t endpointArraySize = 0;
    UA_StatusCode retval = UA_Client_getEndpoints(client, url,
                                                  &endpointArraySize, &endpointArray);
    if (retval != UA_STATUSCODE_GOOD)
    {
        UA_Array_delete(endpointArray, endpointArraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
        UA_Client_delete(client);
        return EXIT_FAILURE;
    }
    printf("%i endpoints found\n", (int)endpointArraySize);
    for (size_t i = 0; i < endpointArraySize; i++)
    {
        printf("URL of endpoint %i is %.*s\n", (int)i,
               (int)endpointArray[i].endpointUrl.length,
               endpointArray[i].endpointUrl.data);
    }
    UA_Array_delete(endpointArray, endpointArraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);

    /* Connect to a server */
    /* anonymous connect would be: retval = UA_Client_connect(client, "opc.tcp://localhost:4840"); */
    // retval = UA_Client_connectUsername(client, "opc.tcp://localhost:4840", "user1", "password");
    retval = UA_Client_connect(client, url);
    if (retval != UA_STATUSCODE_GOOD)
    {
        UA_Client_delete(client);
        return EXIT_FAILURE;
    }

    /* Read attribute */
    UA_Int32 value = 0;
    printf("\nReading the value of node (%d, \"%s\"):\n", ns, node_path);
    UA_Variant *val = UA_Variant_new();
    retval = UA_Client_readValueAttribute(client, UA_NODEID_STRING(ns, node_path), val);
    if (retval == UA_STATUSCODE_GOOD)
    {
        if (UA_Variant_isScalar(val))
        {
            if (val->type == &UA_TYPES[UA_TYPES_INT32])
            {
                value = *(UA_Int32 *)val->data;
                printf("the value is: %i\n", value);
            }
            if (val->type == &UA_TYPES[UA_TYPES_DOUBLE])
            {
                if (val->arrayLength == 0)
                {
                    UA_Double f = *(UA_Double *)val->data;
                    printf("1 the value is: %lf\n", f);
                }
                else
                {
                    UA_Double *f = (UA_Double *)val->data;
                    int k;
                    for (k = 0; k < val->arrayLength; k++)
                        printf("11 the value is:%d val %lf\n", k, f[k]);
                }
            }
            if (val->type == &UA_TYPES[UA_TYPES_FLOAT])
            {
                UA_Float f = *(UA_Float *)val->data;
                printf("6 the value is:%f\n", f);
            }
        }
        else
        {
            printf("not scalar\n");
        }
    }
    else
    {
        printf("Failed. %s\n", UA_StatusCode_name(retval));
    }

    UA_Variant_delete(val);

    UA_Client_disconnect(client);
    UA_Client_delete(client);
    return EXIT_SUCCESS;
}
