//
// Created by magino on 11.4.19.
//

#ifndef MYUASERVER_H
#define MYUASERVER_H

#include <open62541/server.h>
#include <open62541/server_config.h>
#include <open62541/server_config_default.h>
#include <open62541/client.h>
#include <open62541/client_config_default.h>
#include <open62541/plugin/log_stdout.h>
#include <sstream>
#include <list>

#include "server/UaServer.h"
#include "configuration/UaServerCfg.h"
#include "core/UaObjects.h"

class MyUaServer: public UaServer {

private:
    UA_ApplicationDescription BuildAppDescription(UaServerCfg& cfg) {
        UA_ApplicationDescription applicationDescription;

        // To enable mDNS discovery, set application type to discovery server.
        applicationDescription.applicationType = UA_APPLICATIONTYPE_SERVER;

        applicationDescription.applicationName = UA_LOCALIZEDTEXT_ALLOC("en-US", cfg.appName.c_str());
        applicationDescription.applicationUri = UA_String_fromChars(cfg.appUri.c_str());
        applicationDescription.productUri = UA_String_fromChars(cfg.productUri.c_str());

        return applicationDescription;
    }

    UA_MdnsDiscoveryConfiguration BuildmDnsConfiguration(UaServerCfg& cfg) {
        UA_MdnsDiscoveryConfiguration mDnsConfiguration;
        // See http://www.opcfoundation.org/UA/schemas/1.03/ServerCapabilities.csv
        mDnsConfiguration.mdnsServerName = UA_String_fromChars(cfg.mDnsName.c_str());

        auto capabilitiesSize = 2 + cfg.capabilities.size();
        mDnsConfiguration.serverCapabilitiesSize = capabilitiesSize;
        mDnsConfiguration.serverCapabilities = (UA_String *) UA_Array_new(capabilitiesSize, &UA_TYPES[UA_TYPES_STRING]);
        mDnsConfiguration.serverCapabilities[0] = UA_String_fromChars("LDS");
        mDnsConfiguration.serverCapabilities[1] = UA_String_fromChars("DA");
        int j = 0;
        for(int i=2; i<capabilitiesSize; ++i)
            mDnsConfiguration.serverCapabilities[i] = UA_String_fromChars(cfg.capabilities[j].c_str());

        return mDnsConfiguration;
    }
    /**
     * Get the endpoint from the server, where we can call RegisterServer2 (or RegisterServer).
     * This is normally the endpoint with highest supported encryption mode.
     *
     * @param client The client used to get endpoints from server
     * @param discoveryServerUrl The discovery url from the remote server
     * @return The endpoint description (which needs to be freed) or NULL
     */
    UA_EndpointDescription* GetRegisterEndpointFromServer(const char* discoveryServerUrl);
public:
    static const std::string StorageCapability;
    static const std::string TransportCapability;
    static const std::string ActionCapability;

    MyUaServer(UaServerCfg cfg);
    ~MyUaServer() {
        CleanUp();
    }

    void ServerOnNetwork(const UA_ServerOnNetwork* serverOnNetwork) override;
};

#endif //MYUASERVER_H