/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
 *
 *    Copyright 2019 (c) Kalycito Infotech Private Limited
 *    Copyright 2019 NXP.
 *
 */

#include <ex_sss.h>
#include <ex_sss_boot.h>
#include <fsl_sss_se05x_apis.h>
#include <nxEnsure.h>
#include <nxLog_App.h>

#include <open62541/client_highlevel.h>
#include <open62541/plugin/log_stdout.h>
#include <open62541/plugin/securitypolicy.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>

#include <signal.h>
#include <stdlib.h>

#include "common.h"

#include "sss_interface.h"

static ex_sss_boot_ctx_t gex_sss_opc_ua_boot_ctx;
sss_session_t *gSESession = NULL;
UA_Boolean running = true;
UA_Int32 sensor1 = 0;

#define EX_SSS_BOOT_PCONTEXT (&gex_sss_opc_ua_boot_ctx)
#define EX_SSS_BOOT_EXPOSE_ARGC_ARGV 1
#define EX_SSS_BOOT_DO_ERASE 0

#include <ex_sss_main_inc.h>

static void stopHandler(int sig) {
    UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "received ctrl-c");
    running = false;
}

static UA_StatusCode
readSensor1Value(UA_Server *server,
    const UA_NodeId *sessionId, void *sessionContext,
    const UA_NodeId *nodeId, void *nodeContext,
    UA_Boolean sourceTimeStamp, const UA_NumericRange *range,
    UA_DataValue *dataValue) {
    UA_Int32 now = sensor1;
    UA_Variant_setScalarCopy(&dataValue->value, &now,
        &UA_TYPES[UA_TYPES_UINT32]);
    dataValue->hasValue = true;
    return UA_STATUSCODE_GOOD;
}

static UA_StatusCode
writeSensor1Value(UA_Server *server,
    const UA_NodeId *sessionId, void *sessionContext,
    const UA_NodeId *nodeId, void *nodeContext,
    const UA_NumericRange *range, const UA_DataValue *data) {
    UA_UInt16 i = 0;
    char *mem = NULL;
    UA_Int32 val = 0;

    if (strcmp(data->value.type->typeName, "UInt32") == 0)
    {
        mem = data->value.data;
        for (i = 0; i < data->value.type->memSize; i++)
        {
            val |= mem[i] << (8 * i);
        }
        sensor1 = val;
    }
    else
    {
        UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
            "Cannot handle the data type");
    }

    return UA_STATUSCODE_GOOD;
}

static void
addSensor1Variable(UA_Server *server) {
    UA_VariableAttributes attr = UA_VariableAttributes_default;
    attr.displayName = UA_LOCALIZEDTEXT("en-US", "Sensor1");
    attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE;

    UA_NodeId currentNodeId = UA_NODEID_STRING(1, "Sensor1");
    UA_QualifiedName currentName = UA_QUALIFIEDNAME(1, "Sensor1");
    UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
    UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
    UA_NodeId variableTypeNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE);

    UA_DataSource timeDataSource;
    timeDataSource.read = readSensor1Value;
    timeDataSource.write = writeSensor1Value;
    UA_Server_addDataSourceVariableNode(server, currentNodeId, parentNodeId,
        parentReferenceNodeId, currentName,
        variableTypeNodeId, attr,
        timeDataSource, NULL, NULL);
}

//int main(int argc, char* argv[]) {
sss_status_t ex_sss_entry(ex_sss_boot_ctx_t *pCtx){
    UA_ByteString certificate = UA_STRING_NULL;
    signal(SIGINT, stopHandler);
    signal(SIGTERM, stopHandler);

    gex_sss_argc--;
    gSESession = &(pCtx->session);

    if(gex_sss_argc < 3) {
        UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
                     "Missing arguments. Arguments are "
                     "<server-certificate.der> <private-key.der> "
                     "[<trustlist1.crl>, ...]");
        return EXIT_FAILURE;
    }

    /* Load certificate and private key */

    if (strcmp(gex_sss_argv[1], "NULL") == 0)
    {
        /* Read certificate from SE */
        if (sss_interface_init() != 0) {
            return EXIT_FAILURE;
        }
        if (sss_interface_read_certificate(&(certificate.data), &(certificate.length)) != 0) {
            return EXIT_FAILURE;
        }
    }
    else
    {
        certificate = loadFile(gex_sss_argv[1]);
    }

    UA_ByteString privateKey = loadFile(gex_sss_argv[2]);

    /* Load the trustlist */
    size_t trustListSize = 0;
    if(gex_sss_argc > 3)
        trustListSize = (size_t)gex_sss_argc -3;
    UA_STACKARRAY(UA_ByteString, trustList, trustListSize);
    for(size_t i = 0; i < trustListSize; i++)
        trustList[i] = loadFile(gex_sss_argv[i+3]);

    /* Loading of a issuer list, not used in this application */
    size_t issuerListSize = 0;
    UA_ByteString *issuerList = NULL;

    /* Loading of a revocation list currently unsupported */
    UA_ByteString *revocationList = NULL;
    size_t revocationListSize = 0;

    UA_Server *server = UA_Server_new();
    UA_ServerConfig *config = UA_Server_getConfig(server);

    if (privateKey.length != 0)
    {
        UA_realloc(privateKey.data, (privateKey.length + 1) * sizeof(UA_Byte));
        privateKey.data[privateKey.length] = '\0';
        privateKey.length = privateKey.length + 1;
    }

    UA_StatusCode retval =
        UA_ServerConfig_setDefaultWithSecurityPolicies(config, 4840,
                                                       &certificate, &privateKey,
                                                       trustList, trustListSize,
                                                       issuerList, issuerListSize,
                                                       revocationList, revocationListSize);

    UA_ByteString_clear(&certificate);
    UA_ByteString_clear(&privateKey);
    for(size_t i = 0; i < trustListSize; i++)
        UA_ByteString_clear(&trustList[i]);
    if(retval != UA_STATUSCODE_GOOD)
        goto cleanup;

    addSensor1Variable(server);

    retval = UA_Server_run(server, &running);

 cleanup:
    UA_Server_delete(server);
    return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}
