//
// Created by magino on 6. 10. 2019.
//

#ifndef PROCESSCELL_H
#define PROCESSCELL_H

#include <iostream>
#include <vector>
#include <map>
#include <server/UaServer.h>
#include "Reservation.h"
#include "Management.h"

class ProcessCell: public UaNodeContext {
private:
    UaServer& _server;
public:
    static UaNodeId TYPE_NODEID;
    // Browse names - are static because i want reach them from everywhere in code
    static const std::string TYPE_OBJ;
    static const std::string INSTANCE_OBJ;


    static void CreateUaObjectType(UaServer& server) {
        ProcessCell::TYPE_NODEID = UaNodeId(server.GetAppNsIndex(), "PrcssCllType");

        server.AddObjectTypeNode("ProcessCellType",
                                 TYPE_OBJ,
                                 "Process Cell is digital representation of asset in manufacturing, which offer some parametrized service for products.",
                                 TYPE_NODEID);

        UaNodeId tmpNodeId = UaNodeId(server.GetAppNsIndex(), UaNodeContext::GetUniqueNumericNodeId());
        server.AddObjectNode("Info",
                             "Info",
                             "Information about manufacturing cell",
                             false,
                             TYPE_NODEID,
                             tmpNodeId);

        tmpNodeId = UaNodeId(server.GetAppNsIndex(), UaNodeContext::GetUniqueNumericNodeId());
        server.AddObjectNode("Management",
                             "Management",
                             "Management of manufacturing",
                             false,
                             TYPE_NODEID,
                             tmpNodeId);

        tmpNodeId = UaNodeId(server.GetAppNsIndex(), UaNodeContext::GetUniqueNumericNodeId());
        server.AddObjectNode("Manufacturing",
                             "Manufacturing",
                             "Takes care of Manufacturing",
                             false,
                             TYPE_NODEID,
                             tmpNodeId);

        SetTypeLifeCycle(server, TYPE_NODEID);
    }


    ProcessCell(UaServer& server):
            _server(server),
            UaNodeContext(UaNodeId(server.GetAppNsIndex(), UaNodeContext::GetUniqueNumericNodeId())) {}
    ~ProcessCell() override {}

    void Instantiate(UaNodeId& parent, UaNodeId& reference, std::string name) {
        //UaNodeId returnNodeId = server.AddObjectNode(name, ProcessCell::INSTANCE_OBJ, "", false, parent, instanceNodeId, reference, ProcessCell::TYPE_NODEID, this);
        UaNodeId returnNodeId = _server.AddObjectNode(name, ProcessCell::INSTANCE_OBJ, "", false, parent, instanceNodeId, reference, UaNodeId::BaseObjectType, this);
    }

    void DeleteNode() {
        if(!instanceNodeId.IsNull()) {
            _server.DeleteNode(instanceNodeId, true);
            UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Process Cell Node  with node id:%s  has been deleted.",
                        instanceNodeId.ToString().c_str());
        }
    }

    bool TypeConstruct(UaNodeId& instanceNodeId, UaNodeId& typeNodeId, void* instanceCtx = nullptr) override {}
};
UaNodeId ProcessCell::TYPE_NODEID = UaNodeId();

const std::string ProcessCell::TYPE_OBJ = "ProcessCellType";
const std::string ProcessCell::INSTANCE_OBJ = "ProcessCell";

#endif //PROCESSCELL_H