/* 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/.
 *
 *    Copyright 2018 (c) basysKom GmbH <opensource@basyskom.com> (Author: Peter Rustler)
 */

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

#include "client/ua_client_internal.h"

#include <check.h>

#include "testing_clock.h"
#include "testing_networklayers.h"
#include "thread_wrapper.h"

UA_Server *server;
UA_Boolean running;
THREAD_HANDLE server_thread;

UA_Client *client;
UA_UInt32 subId;
UA_NodeId parentNodeId;
UA_NodeId parentReferenceNodeId;
UA_NodeId outNodeId;

UA_Boolean notificationReceived = false;
UA_UInt32 countNotificationReceived = 0;
UA_Double publishingInterval = 500.0;
UA_DataValue lastValue;

THREAD_CALLBACK(serverloop) {
    while(running)
        UA_Server_run_iterate(server, true);
    return 0;
}

static void setup(void) {
    UA_DataValue_init(&lastValue);
    running = true;
    server = UA_Server_new();
    UA_ServerConfig_setDefault(UA_Server_getConfig(server));
    UA_Server_run_startup(server);
    THREAD_CREATE(server_thread, serverloop);

    /* Define the attribute of the double variable node */
    UA_VariableAttributes attr = UA_VariableAttributes_default;
    UA_Double myDouble = 40.0;
    UA_Variant_setScalar(&attr.value, &myDouble, &UA_TYPES[UA_TYPES_DOUBLE]);
    attr.description = UA_LOCALIZEDTEXT("en-US","the answer");
    attr.displayName = UA_LOCALIZEDTEXT("en-US","the answer");
    attr.dataType = UA_TYPES[UA_TYPES_DOUBLE].typeId;
    attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE;
    UA_NodeId doubleNodeId = UA_NODEID_STRING(1, "the.answer");
    UA_QualifiedName doubleName = UA_QUALIFIEDNAME(1, "the answer");
    parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
    parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
    UA_NodeId_init(&outNodeId);
    ck_assert_uint_eq(UA_Server_addVariableNode(server,
                                                doubleNodeId, parentNodeId,
                                                parentReferenceNodeId,
                                                doubleName,
                                                UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
                                                attr,
                                                NULL,
                                                &outNodeId)
                      , UA_STATUSCODE_GOOD);

    /* Add a boolean node */
    UA_Boolean myBool = false;
    UA_Variant_setScalar(&attr.value, &myBool, &UA_TYPES[UA_TYPES_BOOLEAN]);
    attr.description = UA_LOCALIZEDTEXT("en-US","the answer bool");
    attr.displayName = UA_LOCALIZEDTEXT("en-US","the answer bool");
    attr.dataType = UA_TYPES[UA_TYPES_BOOLEAN].typeId;
    ck_assert_uint_eq(UA_Server_addVariableNode(server,
                                                UA_NODEID_STRING(1, "the.bool"),
                                                parentNodeId, parentReferenceNodeId,
                                                UA_QUALIFIEDNAME(1, "the bool"),
                                                UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
                                                attr, NULL, NULL)
                      , UA_STATUSCODE_GOOD);

    client = UA_Client_new();
    UA_ClientConfig_setDefault(UA_Client_getConfig(client));
    UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
    ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);

    UA_Client_recv = client->connection.recv;
    client->connection.recv = UA_Client_recvTesting;

    UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default();
    request.requestedMaxKeepAliveCount = 100;
    UA_CreateSubscriptionResponse response = UA_Client_Subscriptions_create(client, request,
                                                                            NULL, NULL, NULL);
    ck_assert_uint_eq(response.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    subId = response.subscriptionId;
    notificationReceived = false;
    countNotificationReceived = 0;
}

static void teardown(void) {
    ck_assert_uint_eq(UA_Client_Subscriptions_deleteSingle(client, subId)
                      , UA_STATUSCODE_GOOD);

    /* cleanup */
    UA_Client_disconnect(client);
    UA_Client_delete(client);
    UA_NodeId_deleteMembers(&parentNodeId);
    UA_NodeId_deleteMembers(&parentReferenceNodeId);
    UA_NodeId_deleteMembers(&outNodeId);
    running = false;
    THREAD_JOIN(server_thread);
    UA_Server_run_shutdown(server);
    UA_Server_delete(server);
    UA_DataValue_deleteMembers(&lastValue);
}

#ifdef UA_ENABLE_SUBSCRIPTIONS

static void
dataChangeHandler(UA_Client *thisClient, UA_UInt32 thisSubId, void *subContext,
                  UA_UInt32 monId, void *monContext, UA_DataValue *value) {
    notificationReceived = true;
    ++countNotificationReceived;
    UA_DataValue_deleteMembers(&lastValue);
    UA_DataValue_copy(value, &lastValue);
}

static UA_StatusCode
setDouble(UA_Client *thisClient, UA_NodeId node, UA_Double value) {
    UA_Variant variant;
    UA_Variant_setScalar(&variant, &value, &UA_TYPES[UA_TYPES_DOUBLE]);
    return UA_Client_writeValueAttribute(thisClient, node, &variant);
}

static UA_StatusCode waitForNotification(UA_UInt32 notifications, UA_UInt32 maxTries) {
    UA_StatusCode retval = UA_STATUSCODE_GOOD;
    for (UA_UInt32 i = 0; i < maxTries; ++i) {
        UA_fakeSleep((UA_UInt32)publishingInterval + 100);
        retval = UA_Client_run_iterate(client, (UA_UInt16)(publishingInterval + 100));
        if (retval != UA_STATUSCODE_GOOD)
            return retval;
        if (countNotificationReceived == notifications)
            return retval;
    }
    return retval;
}
static UA_Boolean fuzzyLastValueIsEqualTo(UA_Double value) {
    double offset = 0.001;
    if(lastValue.hasValue
            && lastValue.value.type == &UA_TYPES[UA_TYPES_DOUBLE]) {
        double lastDouble = *((UA_Double*)(lastValue.value.data));
        if (lastDouble > value - offset && lastDouble < value + offset) {
            return true;
        }
    }
    return false;
}

START_TEST(Server_MonitoredItemsAbsoluteFilterSetLater) {
    UA_DataValue_init(&lastValue);
    /* define a monitored item with no filter */
    UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
    UA_UInt32 newMonitoredItemIds[1];
    UA_Client_DataChangeNotificationCallback callbacks[1];
    callbacks[0] = dataChangeHandler;
    UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
    void *contexts[1];
    contexts[0] = NULL;

    UA_CreateMonitoredItemsRequest createRequest;
    UA_CreateMonitoredItemsRequest_init(&createRequest);
    createRequest.subscriptionId = subId;
    createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
    createRequest.itemsToCreate = &item;
    createRequest.itemsToCreateSize = 1;
    UA_CreateMonitoredItemsResponse createResponse =
       UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
                                                   callbacks, deleteCallbacks);

    ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(createResponse.resultsSize, 1);
    ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
    newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
    UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);

    // Do we get initial value ?
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 1);

    ck_assert(fuzzyLastValueIsEqualTo(40.0));

    // This should trigger because no filter
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 2);

    ck_assert(fuzzyLastValueIsEqualTo(42.0));

    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 2);

    ck_assert(fuzzyLastValueIsEqualTo(44.0));

    // set back to 40.0
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 40.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 1);

    ck_assert(fuzzyLastValueIsEqualTo(40.0));

    /* modify the monitored item with an absolute filter with deadbandvalue = 2.0 */
    UA_MonitoredItemModifyRequest itemModify;
    UA_MonitoredItemModifyRequest_init(&itemModify);

    itemModify.monitoredItemId = newMonitoredItemIds[0];
    itemModify.requestedParameters.samplingInterval = 250;
    itemModify.requestedParameters.discardOldest = true;
    itemModify.requestedParameters.queueSize = 1;
    itemModify.requestedParameters.clientHandle = newMonitoredItemIds[0];
    UA_DataChangeFilter filter;
    UA_DataChangeFilter_init(&filter);
    filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
    filter.deadbandType = UA_DEADBANDTYPE_ABSOLUTE;
    filter.deadbandValue = 2.0;
    itemModify.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
    itemModify.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
    itemModify.requestedParameters.filter.content.decoded.data = &filter;

    UA_ModifyMonitoredItemsRequest modifyRequest;
    UA_ModifyMonitoredItemsRequest_init(&modifyRequest);
    modifyRequest.subscriptionId = subId;
    modifyRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
    modifyRequest.itemsToModify = &itemModify;
    modifyRequest.itemsToModifySize = 1;

    UA_ModifyMonitoredItemsResponse modifyResponse =
       UA_Client_MonitoredItems_modify(client, modifyRequest);

    ck_assert_uint_eq(modifyResponse.resultsSize, 1);
    ck_assert_uint_eq(modifyResponse.results[0].statusCode, UA_STATUSCODE_GOOD);

    UA_ModifyMonitoredItemsResponse_deleteMembers(&modifyResponse);

    // This should trigger only once for the new filter
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 39.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 1);
    ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(countNotificationReceived, 1);

    ck_assert(fuzzyLastValueIsEqualTo(39.0));

    // This should trigger once at 43.0.
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 1);

    ck_assert(fuzzyLastValueIsEqualTo(43.0));

    // remove monitored item
    UA_DeleteMonitoredItemsRequest deleteRequest;
    UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
    deleteRequest.subscriptionId = subId;
    deleteRequest.monitoredItemIds = newMonitoredItemIds;
    deleteRequest.monitoredItemIdsSize = 1;

    UA_DeleteMonitoredItemsResponse deleteResponse =
        UA_Client_MonitoredItems_delete(client, deleteRequest);

    ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(deleteResponse.resultsSize, 1);
    ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);

    UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);

}
END_TEST

START_TEST(Server_MonitoredItemsAbsoluteFilterSetOnCreateRemoveLater) {
    UA_DataValue_init(&lastValue);
    /* define a monitored item with absolute filter */
    UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
    UA_DataChangeFilter filter;
    UA_DataChangeFilter_init(&filter);
    filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
    filter.deadbandType = UA_DEADBANDTYPE_ABSOLUTE;
    filter.deadbandValue = 2.0;
    item.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
    item.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
    item.requestedParameters.filter.content.decoded.data = &filter;
    UA_UInt32 newMonitoredItemIds[1];
    UA_Client_DataChangeNotificationCallback callbacks[1];
    callbacks[0] = dataChangeHandler;
    UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
    void *contexts[1];
    contexts[0] = NULL;

    UA_CreateMonitoredItemsRequest createRequest;
    UA_CreateMonitoredItemsRequest_init(&createRequest);
    createRequest.subscriptionId = subId;
    createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
    createRequest.itemsToCreate = &item;
    createRequest.itemsToCreateSize = 1;
    UA_CreateMonitoredItemsResponse createResponse =
       UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
                                                   callbacks, deleteCallbacks);

    ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(createResponse.resultsSize, 1);
    ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
    newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
    UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);

    // Do we get initial value ?
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 1);

    ck_assert(fuzzyLastValueIsEqualTo(40.0));

    // This should not trigger because of filter
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, false);
    ck_assert_uint_eq(countNotificationReceived, 0);

    ck_assert(fuzzyLastValueIsEqualTo(40.0));

    // This should trigger once at 43.0.
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 1);

    ck_assert(fuzzyLastValueIsEqualTo(43.0));

    // set back to 40.0
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 40.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 1);

    ck_assert(fuzzyLastValueIsEqualTo(40.0));

    /* modify the monitored item with no filter */
    UA_MonitoredItemModifyRequest itemModify;
    UA_MonitoredItemModifyRequest_init(&itemModify);

    itemModify.monitoredItemId = newMonitoredItemIds[0];
    itemModify.requestedParameters.samplingInterval = 250;
    itemModify.requestedParameters.discardOldest = true;
    itemModify.requestedParameters.queueSize = 1;
    itemModify.requestedParameters.clientHandle = newMonitoredItemIds[0];
    UA_DataChangeFilter unsetfilter;
    UA_DataChangeFilter_init(&unsetfilter);
    unsetfilter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
    unsetfilter.deadbandType = UA_DEADBANDTYPE_NONE;
    unsetfilter.deadbandValue = 0.0;
    itemModify.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
    itemModify.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
    itemModify.requestedParameters.filter.content.decoded.data = &unsetfilter;

    UA_ModifyMonitoredItemsRequest modifyRequest;
    UA_ModifyMonitoredItemsRequest_init(&modifyRequest);
    modifyRequest.subscriptionId = subId;
    modifyRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
    modifyRequest.itemsToModify = &itemModify;
    modifyRequest.itemsToModifySize = 1;

    UA_ModifyMonitoredItemsResponse modifyResponse =
       UA_Client_MonitoredItems_modify(client, modifyRequest);

    ck_assert_uint_eq(modifyResponse.resultsSize, 1);
    ck_assert_uint_eq(modifyResponse.results[0].statusCode, UA_STATUSCODE_GOOD);

    UA_ModifyMonitoredItemsResponse_deleteMembers(&modifyResponse);

    // This should trigger because now we do not filter
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 2);

    ck_assert(fuzzyLastValueIsEqualTo(42.0));

    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 2);

    ck_assert(fuzzyLastValueIsEqualTo(44.0));

    // remove monitored item
    UA_DeleteMonitoredItemsRequest deleteRequest;
    UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
    deleteRequest.subscriptionId = subId;
    deleteRequest.monitoredItemIds = newMonitoredItemIds;
    deleteRequest.monitoredItemIdsSize = 1;

    UA_DeleteMonitoredItemsResponse deleteResponse =
        UA_Client_MonitoredItems_delete(client, deleteRequest);

    ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(deleteResponse.resultsSize, 1);
    ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);

    UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);

}
END_TEST

START_TEST(Server_MonitoredItemsPercentFilterSetLater) {
    UA_DataValue_init(&lastValue);
    /* define a monitored item with no filter */
    UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
    UA_UInt32 newMonitoredItemIds[1];
    UA_Client_DataChangeNotificationCallback callbacks[1];
    callbacks[0] = dataChangeHandler;
    UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
    void *contexts[1];
    contexts[0] = NULL;

    UA_CreateMonitoredItemsRequest createRequest;
    UA_CreateMonitoredItemsRequest_init(&createRequest);
    createRequest.subscriptionId = subId;
    createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
    createRequest.itemsToCreate = &item;
    createRequest.itemsToCreateSize = 1;
    UA_CreateMonitoredItemsResponse createResponse =
       UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
                                                   callbacks, deleteCallbacks);

    ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(createResponse.resultsSize, 1);
    ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
    newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
    UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);

    // Do we get initial value ?
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 1);

    ck_assert(fuzzyLastValueIsEqualTo(40.0));

    // This should trigger because no filter
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 2);

    ck_assert(fuzzyLastValueIsEqualTo(42.0));

    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 2);

    ck_assert(fuzzyLastValueIsEqualTo(44.0));

    // set back to 40.0
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 40.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 1);

    ck_assert(fuzzyLastValueIsEqualTo(40.0));

    /* modify the monitored item with an percent filter with deadbandvalue = 2.0 */
    UA_MonitoredItemModifyRequest itemModify;
    UA_MonitoredItemModifyRequest_init(&itemModify);

    itemModify.monitoredItemId = newMonitoredItemIds[0];
    itemModify.requestedParameters.samplingInterval = 250;
    itemModify.requestedParameters.discardOldest = true;
    itemModify.requestedParameters.queueSize = 1;
    itemModify.requestedParameters.clientHandle = newMonitoredItemIds[0];
    UA_DataChangeFilter filter;
    UA_DataChangeFilter_init(&filter);
    filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
    filter.deadbandType = UA_DEADBANDTYPE_PERCENT;
    filter.deadbandValue = 2.0;
    itemModify.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
    itemModify.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
    itemModify.requestedParameters.filter.content.decoded.data = &filter;

    UA_ModifyMonitoredItemsRequest modifyRequest;
    UA_ModifyMonitoredItemsRequest_init(&modifyRequest);
    modifyRequest.subscriptionId = subId;
    modifyRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
    modifyRequest.itemsToModify = &itemModify;
    modifyRequest.itemsToModifySize = 1;

    UA_ModifyMonitoredItemsResponse modifyResponse =
       UA_Client_MonitoredItems_modify(client, modifyRequest);

    ck_assert_uint_eq(modifyResponse.resultsSize, 1);
    ck_assert_uint_eq(modifyResponse.results[0].statusCode, UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED);

    UA_ModifyMonitoredItemsResponse_deleteMembers(&modifyResponse);

    // This should trigger because setting filter failed
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 2);

    ck_assert(fuzzyLastValueIsEqualTo(42.0));

    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 2);

    ck_assert(fuzzyLastValueIsEqualTo(44.0));

    // remove monitored item
    UA_DeleteMonitoredItemsRequest deleteRequest;
    UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
    deleteRequest.subscriptionId = subId;
    deleteRequest.monitoredItemIds = newMonitoredItemIds;
    deleteRequest.monitoredItemIdsSize = 1;

    UA_DeleteMonitoredItemsResponse deleteResponse =
        UA_Client_MonitoredItems_delete(client, deleteRequest);

    ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(deleteResponse.resultsSize, 1);
    ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);

    UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);

}
END_TEST

START_TEST(Server_MonitoredItemsNoFilter) {
    UA_DataValue_init(&lastValue);
    /* define a monitored item with an absolute filter with deadbandvalue = 2.0 */
    UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
    UA_UInt32 newMonitoredItemIds[1];
    UA_Client_DataChangeNotificationCallback callbacks[1];
    callbacks[0] = dataChangeHandler;
    UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
    void *contexts[1];
    contexts[0] = NULL;

    UA_CreateMonitoredItemsRequest createRequest;
    UA_CreateMonitoredItemsRequest_init(&createRequest);
    createRequest.subscriptionId = subId;
    createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
    createRequest.itemsToCreate = &item;
    createRequest.itemsToCreateSize = 1;
    UA_CreateMonitoredItemsResponse createResponse =
       UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
                                                   callbacks, deleteCallbacks);

    ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(createResponse.resultsSize, 1);
    ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
    newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
    UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);

    // Do we get initial value ?
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 1);

    ck_assert(fuzzyLastValueIsEqualTo(40.0));

    // This should trigger because no filter
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived,  2);

    ck_assert(fuzzyLastValueIsEqualTo(42.0));

    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 2);

    ck_assert(fuzzyLastValueIsEqualTo(44.0));

    // remove monitored item
    UA_DeleteMonitoredItemsRequest deleteRequest;
    UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
    deleteRequest.subscriptionId = subId;
    deleteRequest.monitoredItemIds = newMonitoredItemIds;
    deleteRequest.monitoredItemIdsSize = 1;

    UA_DeleteMonitoredItemsResponse deleteResponse =
        UA_Client_MonitoredItems_delete(client, deleteRequest);

    ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(deleteResponse.resultsSize, 1);
    ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);

    UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);
}
END_TEST

/* Test if an absolute filter can be added for boolean variables */
START_TEST(Server_MonitoredItemsAbsoluteFilterOnBool) {
    UA_DataValue_init(&lastValue);
    /* define a monitored item with an absolute filter with deadbandvalue = 2.0 */
    UA_MonitoredItemCreateRequest item =
        UA_MonitoredItemCreateRequest_default(UA_NODEID_STRING(1, "the.bool"));;
    UA_DataChangeFilter filter;
    UA_DataChangeFilter_init(&filter);
    filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
    filter.deadbandType = UA_DEADBANDTYPE_ABSOLUTE;
    filter.deadbandValue = 0.5;
    item.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
    item.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
    item.requestedParameters.filter.content.decoded.data = &filter;
    UA_Client_DataChangeNotificationCallback callbacks[1];
    callbacks[0] = dataChangeHandler;
    UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
    void *contexts[1];
    contexts[0] = NULL;

    UA_CreateMonitoredItemsRequest createRequest;
    UA_CreateMonitoredItemsRequest_init(&createRequest);
    createRequest.subscriptionId = subId;
    createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
    createRequest.itemsToCreate = &item;
    createRequest.itemsToCreateSize = 1;
    UA_CreateMonitoredItemsResponse createResponse =
       UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
                                                  callbacks, deleteCallbacks);

    ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(createResponse.resultsSize, 1);
    ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
    UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);
}
END_TEST

START_TEST(Server_MonitoredItemsAbsoluteFilterSetOnCreate) {
    UA_DataValue_init(&lastValue);
    /* define a monitored item with an absolute filter with deadbandvalue = 2.0 */
    UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
    UA_DataChangeFilter filter;
    UA_DataChangeFilter_init(&filter);
    filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
    filter.deadbandType = UA_DEADBANDTYPE_ABSOLUTE;
    filter.deadbandValue = 2.0;
    item.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
    item.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
    item.requestedParameters.filter.content.decoded.data = &filter;
    UA_UInt32 newMonitoredItemIds[1];
    UA_Client_DataChangeNotificationCallback callbacks[1];
    callbacks[0] = dataChangeHandler;
    UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
    void *contexts[1];
    contexts[0] = NULL;

    UA_CreateMonitoredItemsRequest createRequest;
    UA_CreateMonitoredItemsRequest_init(&createRequest);
    createRequest.subscriptionId = subId;
    createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
    createRequest.itemsToCreate = &item;
    createRequest.itemsToCreateSize = 1;
    UA_CreateMonitoredItemsResponse createResponse =
       UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
                                                   callbacks, deleteCallbacks);

    ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(createResponse.resultsSize, 1);
    ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
    newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
    UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);

    // Do we get initial value ?
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 1);

    ck_assert(fuzzyLastValueIsEqualTo(40.0));

    // This should not trigger because of filter
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, false);
    ck_assert_uint_eq(countNotificationReceived, 0);

    ck_assert(fuzzyLastValueIsEqualTo(40.0));

    // This should trigger once at 43.0.
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, true);
    ck_assert_uint_eq(countNotificationReceived, 1);

    ck_assert(fuzzyLastValueIsEqualTo(43.0));

    // remove monitored item
    UA_DeleteMonitoredItemsRequest deleteRequest;
    UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
    deleteRequest.subscriptionId = subId;
    deleteRequest.monitoredItemIds = newMonitoredItemIds;
    deleteRequest.monitoredItemIdsSize = 1;

    UA_DeleteMonitoredItemsResponse deleteResponse =
        UA_Client_MonitoredItems_delete(client, deleteRequest);

    ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(deleteResponse.resultsSize, 1);
    ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);

    UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);

}
END_TEST

START_TEST(Server_MonitoredItemsPercentFilterSetOnCreate) {
    UA_DataValue_init(&lastValue);
    /* define a monitored item with an percent filter with deadbandvalue = 2.0 */
    UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
    UA_DataChangeFilter filter;
    UA_DataChangeFilter_init(&filter);
    filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
    filter.deadbandType = UA_DEADBANDTYPE_PERCENT;
    filter.deadbandValue = 2.0;
    item.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
    item.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
    item.requestedParameters.filter.content.decoded.data = &filter;
    UA_UInt32 newMonitoredItemIds[1];
    UA_Client_DataChangeNotificationCallback callbacks[1];
    callbacks[0] = dataChangeHandler;
    UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
    void *contexts[1];
    contexts[0] = NULL;

    UA_CreateMonitoredItemsRequest createRequest;
    UA_CreateMonitoredItemsRequest_init(&createRequest);
    createRequest.subscriptionId = subId;
    createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
    createRequest.itemsToCreate = &item;
    createRequest.itemsToCreateSize = 1;
    UA_CreateMonitoredItemsResponse createResponse =
       UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
                                                   callbacks, deleteCallbacks);

    ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(createResponse.resultsSize, 1);
    ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED);
    newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
    UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);

    // Do we get initial value ? (must fail)
    notificationReceived = false;
    countNotificationReceived = 0;
    ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(notificationReceived, false);
    ck_assert_uint_eq(countNotificationReceived, 0);

    // remove monitored item (must fail)
    UA_DeleteMonitoredItemsRequest deleteRequest;
    UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
    deleteRequest.subscriptionId = subId;
    deleteRequest.monitoredItemIds = newMonitoredItemIds;
    deleteRequest.monitoredItemIdsSize = 1;

    UA_DeleteMonitoredItemsResponse deleteResponse =
        UA_Client_MonitoredItems_delete(client, deleteRequest);

    ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
    ck_assert_uint_eq(deleteResponse.resultsSize, 1);
    ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_BADMONITOREDITEMIDINVALID);

    UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);
}
END_TEST

#endif /*UA_ENABLE_SUBSCRIPTIONS*/

static Suite* testSuite_Client(void) {
    Suite *s = suite_create("Server monitored item filter");
    TCase *tc_server = tcase_create("Server monitored item filter Basic");
    tcase_add_checked_fixture(tc_server, setup, teardown);
#ifdef UA_ENABLE_SUBSCRIPTIONS
    tcase_add_test(tc_server, Server_MonitoredItemsNoFilter);
    tcase_add_test(tc_server, Server_MonitoredItemsAbsoluteFilterSetOnCreate);
    tcase_add_test(tc_server, Server_MonitoredItemsAbsoluteFilterOnBool);
    tcase_add_test(tc_server, Server_MonitoredItemsAbsoluteFilterSetLater);
    tcase_add_test(tc_server, Server_MonitoredItemsAbsoluteFilterSetOnCreateRemoveLater);
    tcase_add_test(tc_server, Server_MonitoredItemsPercentFilterSetOnCreate);
    tcase_add_test(tc_server, Server_MonitoredItemsPercentFilterSetLater);
#endif /* UA_ENABLE_SUBSCRIPTIONS */
    suite_add_tcase(s, tc_server);

    return s;
}

int main(void) {
    Suite *s = testSuite_Client();
    SRunner *sr = srunner_create(s);
    srunner_set_fork_status(sr, CK_NOFORK);
    srunner_run_all(sr,CK_NORMAL);
    int number_failed = srunner_ntests_failed(sr);
    srunner_free(sr);
    return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
