/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <open62541/client.h>
#include <open62541/client_config_default.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>

#include "server/ua_server_internal.h"

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

#include "thread_wrapper.h"

UA_Server *server_translate_browse;
UA_Boolean *running_translate_browse;
THREAD_HANDLE server_thread_translate_browse;

THREAD_CALLBACK(serverloop_register) {
    while (*running_translate_browse)
        UA_Server_run_iterate(server_translate_browse, true);
    return 0;
}

static void setup_server(void) {
    // start server
    running_translate_browse = UA_Boolean_new();
    *running_translate_browse = true;

    server_translate_browse = UA_Server_new();
    UA_ServerConfig *server_translate_config = UA_Server_getConfig(server_translate_browse);
    UA_ServerConfig_setDefault(server_translate_config);

    UA_String_deleteMembers(&server_translate_config->applicationDescription.applicationUri);
    server_translate_config->applicationDescription.applicationUri =
        UA_String_fromChars("urn:open62541.test.server_translate_browse");
    UA_Server_run_startup(server_translate_browse);
    THREAD_CREATE(server_thread_translate_browse, serverloop_register);
}

static void teardown_server(void) {
    *running_translate_browse = false;
    THREAD_JOIN(server_thread_translate_browse);
    UA_Server_run_shutdown(server_translate_browse);
    UA_Boolean_delete(running_translate_browse);
    UA_Server_delete(server_translate_browse);
}

static size_t
browseWithMaxResults(UA_Server *server, UA_NodeId nodeId, UA_UInt32 maxResults) {
    UA_BrowseDescription bd;
    UA_BrowseDescription_init(&bd);
    bd.nodeId = nodeId;
    bd.resultMask = UA_BROWSERESULTMASK_ALL;
    bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;
    UA_BrowseResult br = UA_Server_browse(server, maxResults, &bd);
    ck_assert_int_eq(br.statusCode, UA_STATUSCODE_GOOD);
    ck_assert(br.referencesSize > 0);
    ck_assert(br.referencesSize <= maxResults);

    size_t total = br.referencesSize;
    UA_ByteString cp = br.continuationPoint;
    br.continuationPoint = UA_BYTESTRING_NULL;
    UA_BrowseResult_deleteMembers(&br);

    while(cp.length > 0) {
        br = UA_Server_browseNext(server, false, &cp);
        ck_assert(br.referencesSize > 0);
        ck_assert(br.referencesSize <= maxResults);
        UA_ByteString_deleteMembers(&cp);
        cp = br.continuationPoint;
        br.continuationPoint = UA_BYTESTRING_NULL;
        total += br.referencesSize;
        UA_BrowseResult_deleteMembers(&br);
    }

    return total;
}

START_TEST(Service_Browse_WithMaxResults) {
    UA_Server *server = UA_Server_new();
    UA_ServerConfig_setDefault(UA_Server_getConfig(server));

    UA_BrowseDescription bd;
    UA_BrowseDescription_init(&bd);
    bd.resultMask = UA_BROWSERESULTMASK_ALL;
    bd.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER);
    bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;
    UA_BrowseResult br = UA_Server_browse(server, 0, &bd);

    ck_assert_int_eq(br.statusCode, UA_STATUSCODE_GOOD);
    ck_assert(br.referencesSize > 0);

    size_t total = br.referencesSize;
    UA_BrowseResult_deleteMembers(&br);

    for(UA_UInt32 i = 1; i <= total; i++) {
        size_t sum_total =
            browseWithMaxResults(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER), i);
        ck_assert_int_eq(total, sum_total);
    }
    
    UA_Server_delete(server);
}
END_TEST

START_TEST(Service_Browse_WithBrowseName) {
    UA_Server *server = UA_Server_new();
    UA_ServerConfig_setDefault(UA_Server_getConfig(server));

    UA_BrowseDescription bd;
    UA_BrowseDescription_init(&bd);
    bd.resultMask = UA_BROWSERESULTMASK_BROWSENAME;
    bd.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
    bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
    bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;

    UA_BrowseResult br = UA_Server_browse(server, 0, &bd);

    ck_assert_int_eq(br.statusCode, UA_STATUSCODE_GOOD);
    ck_assert(br.referencesSize > 0);
    ck_assert(!UA_String_equal(&br.references[0].browseName.name, &UA_STRING_NULL));

    UA_BrowseResult_deleteMembers(&br);
    UA_Server_delete(server);
}
END_TEST

START_TEST(Service_Browse_Recursive) {
    UA_Server *server = UA_Server_new();
    UA_ServerConfig_setDefault(UA_Server_getConfig(server));

    size_t resultSize = 0;
    UA_ExpandedNodeId *result = NULL;

    UA_BrowseDescription bd;
    UA_BrowseDescription_init(&bd);
    bd.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_NAMESPACEARRAY);
    bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HIERARCHICALREFERENCES);
    bd.includeSubtypes = true;
    bd.browseDirection = UA_BROWSEDIRECTION_INVERSE;
    UA_StatusCode retval = UA_Server_browseRecursive(server, &bd, &resultSize, &result);

    ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(resultSize, 3);

    UA_NodeId expected[3];
    expected[0] = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER);
    expected[1] = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
    expected[2] = UA_NODEID_NUMERIC(0, UA_NS0ID_ROOTFOLDER);

    for(size_t i = 0; i < resultSize; i++) {
        ck_assert(UA_NodeId_equal(&expected[i], &result[i].nodeId));
    }

    UA_Array_delete(result, resultSize, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
    UA_Server_delete(server);
}
END_TEST

START_TEST(Service_TranslateBrowsePathsToNodeIds) {
    UA_Client *client = UA_Client_new();
    UA_ClientConfig_setDefault(UA_Client_getConfig(client));

    UA_StatusCode retVal = UA_Client_connect(client, "opc.tcp://localhost:4840");
    ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD);

    // Just for testing we want to translate the following path to its corresponding node id
    // /Objects/Server/ServerStatus/State
    // Equals the following node IDs:
    // /85/2253/2256/2259

#define BROWSE_PATHS_SIZE 3
    char *paths[BROWSE_PATHS_SIZE] = {"Server", "ServerStatus", "State"};
    UA_UInt32 ids[BROWSE_PATHS_SIZE] = {UA_NS0ID_ORGANIZES, UA_NS0ID_HASCOMPONENT, UA_NS0ID_HASCOMPONENT};
    UA_BrowsePath browsePath;
    UA_BrowsePath_init(&browsePath);
    browsePath.startingNode = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
    browsePath.relativePath.elements = (UA_RelativePathElement*)UA_Array_new(BROWSE_PATHS_SIZE, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]);
    browsePath.relativePath.elementsSize = BROWSE_PATHS_SIZE;

    for(size_t i = 0; i < BROWSE_PATHS_SIZE; i++) {
        UA_RelativePathElement *elem = &browsePath.relativePath.elements[i];
        elem->referenceTypeId = UA_NODEID_NUMERIC(0, ids[i]);
        elem->targetName = UA_QUALIFIEDNAME_ALLOC(0, paths[i]);
    }

    UA_TranslateBrowsePathsToNodeIdsRequest request;
    UA_TranslateBrowsePathsToNodeIdsRequest_init(&request);
    request.browsePaths = &browsePath;
    request.browsePathsSize = 1;

    UA_TranslateBrowsePathsToNodeIdsResponse response = UA_Client_Service_translateBrowsePathsToNodeIds(client, request);

    ck_assert_int_eq(response.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    ck_assert_int_eq(response.resultsSize, 1);

    ck_assert_int_eq(response.results[0].targetsSize, 1);
    ck_assert_int_eq(response.results[0].targets[0].targetId.nodeId.identifierType, UA_NODEIDTYPE_NUMERIC);
    ck_assert_int_eq(response.results[0].targets[0].targetId.nodeId.identifier.numeric, UA_NS0ID_SERVER_SERVERSTATUS_STATE);

    UA_BrowsePath_deleteMembers(&browsePath);
    UA_TranslateBrowsePathsToNodeIdsResponse_deleteMembers(&response);
    retVal = UA_Client_disconnect(client);
    ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD);
    UA_Client_delete(client);
}
END_TEST

START_TEST(BrowseSimplifiedBrowsePath) {
    UA_QualifiedName objectsName = UA_QUALIFIEDNAME(0, "Objects");
    UA_BrowsePathResult bpr =
        UA_Server_browseSimplifiedBrowsePath(server_translate_browse,
                                             UA_NODEID_NUMERIC(0, UA_NS0ID_ROOTFOLDER),
                                             1, &objectsName);

    ck_assert_int_eq(bpr.targetsSize, 1);

    UA_BrowsePathResult_deleteMembers(&bpr);
}
END_TEST

static Suite *testSuite_Service_TranslateBrowsePathsToNodeIds(void) {
    Suite *s = suite_create("Service_TranslateBrowsePathsToNodeIds");
    TCase *tc_browse = tcase_create("Browse Service");
    tcase_add_test(tc_browse, Service_Browse_WithBrowseName);
    tcase_add_test(tc_browse, Service_Browse_WithMaxResults);
    tcase_add_test(tc_browse, Service_Browse_Recursive);
    suite_add_tcase(s, tc_browse);

    TCase *tc_translate = tcase_create("TranslateBrowsePathsToNodeIds");
    tcase_add_unchecked_fixture(tc_translate, setup_server, teardown_server);
    tcase_add_test(tc_translate, Service_TranslateBrowsePathsToNodeIds);
    tcase_add_test(tc_translate, BrowseSimplifiedBrowsePath);

    suite_add_tcase(s, tc_translate);
    return s;
}

int main(void) {
    int number_failed = 0;

    Suite *s;
    SRunner *sr;

    s = testSuite_Service_TranslateBrowsePathsToNodeIds();
    sr = srunner_create(s);
    srunner_set_fork_status(sr, CK_NOFORK);
    srunner_run_all(sr, CK_NORMAL);
    number_failed += srunner_ntests_failed(sr);
    srunner_free(sr);

    return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}


