

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/_/
//_/_/  This file is part of CMSDK version 2.0.0.170915_Beta4 (15 September 2017)
//_/_/  
//_/_/  developed by
//_/_/  
//_/_/  Communicative Machines Ltd. 
//_/_/    http://cmlabs.com/
//_/_/  Copyright (c) 2017
//_/_/  
//_/_/  in collaboration with 
//_/_/  
//_/_/  Icelandic Institute for Intelligent Machines ses
//_/_/    Menntavegur 1
//_/_/    101 Reykjavik
//_/_/    ICELAND
//_/_/    http://www.iiim.is/
//_/_/
//_/_/  and is released under the following
//_/_/  
//_/_/  EXTENDED BSD License
//_/_/
//_/_/  Redistribution and use in source and binary forms, with or without
//_/_/  modification, is permitted provided that the following conditions 
//_/_/  are met:
//_/_/
//_/_/  - Redistributions of source code must retain the above copyright 
//_/_/    and collaboration notice, this list of conditions and the following 
//_/_/    disclaimer.
//_/_/
//_/_/  - Redistributions in binary form must reproduce the above copyright 
//_/_/    notice, this list of conditions and the following disclaimer in the 
//_/_/    documentation and/or other materials provided with the distribution.
//_/_/
//_/_/  - Neither the name of its copyright holders nor the names of its 
//_/_/    contributors may be used to endorse or promote products derived from 
//_/_/    this software without specific prior written permission.
//_/_/
//_/_/  - CADIA Clause: The license granted in and to the software under this 
//_/_/    agreement is a limited-use license. The software may not be used in 
//_/_/    furtherance of: (i) intentionally causing bodily injury or severe 
//_/_/    emotional harm to any person; (ii) invading the personal privacy or 
//_/_/    violating the human rights of any person; or (iii) committing or 
//_/_/    preparing for any act of war. 
//_/_/
//_/_/  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
//_/_/  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
//_/_/  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
//_/_/  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
//_/_/  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
//_/_/  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
//_/_/  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
//_/_/  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
//_/_/  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
//_/_/  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
//_/_/  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//_/_/
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#if !defined(_MEMORYMAPS_H_)
#define _MEMORYMAPS_H_

#include "MemoryManager.h"

namespace cmlabs {

#define ID_SYSPAGE			0
#define ID_PAGEPOOL			1
#define ID_EOLPAGE			2
#define ID_QUEUEPAGE		3
#define ID_COMPMAPPAGE		4
#define ID_TYPEMAPPAGE		5
#define ID_TOPICMAPPAGE		6
//#define ID_NODEMAPPAGE		7
#define ID_QUEUEMAPPAGE		7
#define ID_PROCESSMAPPAGE	8
#define ID_REQUESTMAPPAGE	9
#define ID_CRANKMAPPAGE		10
#define ID_CONTEXTMAPPAGE	11
#define RESERVEDPAGECOUNT	12

#define SIGNALQ_ID 0
#define MSGQ_ID 1
#define REQQ_ID 2
#define CMDQ_ID 3

struct TypeMapHeader {
	uint32 size; // total size of map structure in bytes
	uint32 count; // number of entries
	uint32 bitFieldSize; // number of bytes in the bitfield
	// Bitfield
	// Entries
};

struct TypeMapEntry {
	uint16 id; // id, corresponds to the index in map
	uint64 time; // timestamp when entered
	char name[MAXKEYNAMELEN+1]; // name in text
	uint32 key;
};

struct ContextMapHeader {
	uint32 size; // total size of map structure in bytes
	uint32 count; // number of entries
	uint32 bitFieldSize; // number of bytes in the bitfield
	// Bitfield
	// Entries
};

struct ContextMapEntry {
	uint16 id; // id, corresponds to the index in map
	uint64 time; // timestamp when entered
	char name[MAXKEYNAMELEN+1]; // name in text
	uint32 key;
};

struct TopicMapHeader {
	uint32 size; // total size of map structure in bytes
	uint32 count; // number of entries
	uint32 bitFieldSize; // number of bytes in the bitfield
	// Bitfield
	// Entries
};

struct TopicMapEntry {
	uint32 id; // id, corresponds to the index in map
	uint64 time; // timestamp when entered
	char name[MAXKEYNAMELEN+1]; // name in text
	uint32 key;
};

//struct NodeMapHeader {
//	uint32 size; // total size of map structure in bytes
//	uint32 count; // number of entries
//	uint32 bitFieldSize; // number of bytes in the bitfield
//	// Bitfield
//	// Entries
//};
//
//struct NodeMapEntry {
//	uint16 id; // id, corresponds to the index in map
//	uint64 time; // timestamp when entered
//	char name[MAXKEYNAMELEN+1]; // name in text
//	uint64 key; // 32bit IP4, 16bit port, 16bit unused
//};

struct CrankMapHeader {
	uint32 size; // total size of map structure in bytes
	uint32 count; // number of entries
	uint32 bitFieldSize; // number of bytes in the bitfield
	// Bitfield
	// Entries
};

struct CrankMapEntry {
	uint16 id; // id, corresponds to the index in map
	uint64 time; // timestamp when entered
	char name[MAXKEYNAMELEN+1]; // name in text
	char function[MAXKEYNAMELEN+1]; // name in text
	char libraryFilename[MAXKEYNAMELEN+1]; // name in text
	char script[MAXSCRIPTLEN+1]; // script in text
	uint64 key; // 32bit IP4, 16bit port, 16bit unused
};

struct QueueMapHeader {
	uint32 size; // total size of map structure in bytes
	uint32 count; // number of entries
	uint32 bitFieldSize; // number of bytes in the bitfield
	// Bitfield
	// Entries
};

struct QueueMapEntry {
	uint16 id; // id, corresponds to the index in map
	uint64 time; // timestamp when entered
	char name[MAXKEYNAMELEN+1]; // name in text
	uint32 key; // 32bit IP4, 16bit port, 16bit unused
};

#define PROC_ERROR	0
#define PROC_INIT	1
#define PROC_IDLE	2
#define PROC_READY	3
#define PROC_ACTIVE	4

struct ProcessMapHeader {
	uint32 size; // total size of map structure in bytes
	uint32 count; // number of entries
	uint32 bitFieldSize; // number of bytes in the bitfield
	// Bitfield
	// Entries
};

struct ProcessMapEntry {
	uint32 id; // id, corresponds to the index in map
	uint64 time; // timestamp when entered
	uint64 lastseen; // timestamp when entered
	uint8 status; // status of the process
	char name[MAXKEYNAMELEN+1]; // name in text
	uint32 key;
	char commandline[MAXCOMMANDLINELEN+1]; // commandline in text
	uint32 signalQID; // id of Signal queue
	uint32 messageQID; // id of Message queue
	uint32 timeQID; // id of Time queue
	uint32 requestQID; // id of Request queue
	uint32 commandQID; // id of Command queue
};

struct RequestMapHeader {
	uint32 size; // total size of map structure in bytes
	uint32 count; // number of entries
	uint32 bitFieldSize; // number of bytes in the bitfield
	// Bitfield
	// Entries
};

struct RequestMapEntry {
	uint32 id; // id, corresponds to the index in map
	uint64 time; // timestamp when entered
	char name[MAXKEYNAMELEN+1]; // name in text
	uint32 key;
	uint8 status; // status of the process
	uint32 from; // id of component making the request
	uint32 to; // id of component processing the request
	uint64 dataMessageID; // id of Data Message
	uint64 dataMessageEOL; // eol of Data Message
};

struct GenericMapHeader {
	uint32 size; // total size of map structure in bytes
	uint32 count; // number of entries
	uint32 bitFieldSize; // number of bytes in the bitfield
	// Bitfield
	// Entries
};


inline uint16 TypePageID(TypeMapEntry* e) {return ID_TYPEMAPPAGE;}
inline uint16 TypePageID(TopicMapEntry* e) {return ID_TOPICMAPPAGE;}
//inline uint16 TypePageID(NodeMapEntry* e) {return ID_NODEMAPPAGE;}
inline uint16 TypePageID(QueueMapEntry* e) {return ID_QUEUEMAPPAGE;}
inline uint16 TypePageID(ProcessMapEntry* e) {return ID_PROCESSMAPPAGE;}
inline uint16 TypePageID(RequestMapEntry* e) {return ID_REQUESTMAPPAGE;}
inline uint16 TypePageID(CrankMapEntry* e) {return ID_CRANKMAPPAGE;}
inline uint16 TypePageID(ContextMapEntry* e) {return ID_CONTEXTMAPPAGE;}

#define REQ_CREATED				1
#define REQ_RECEIVED_LOCAL		2
#define REQ_RECEIVED_REMOTE		3
#define REQ_PROCESSING_LOCAL	4
#define REQ_PROCESSING_REMOTE	5
#define REQ_REPLY_READY			6
#define REQ_FAILED				7
#define REQ_FAILED_DATA			8
#define REQ_FAILED_NODATA		9
#define REQ_FAILED_DATA_EOL		10
#define REQ_SUCCESS				11
#define REQ_SUCCESS_DATA		12
#define REQ_SUCCESS_NODATA		13
#define REQ_SUCCESS_DATA_EOL	14



class MemoryMaps {
public:
	// TypeLevelMap
	static bool CreateNewTypeLevel(uint16 id, const char* name, uint64 time = 0);
	static bool GetTypeLevelName(uint16 id, char* name, uint32 maxSize);
	static bool GetTypeLevelID(const char* name, uint16 &id);
	static bool DeleteTypeLevel(const char* name);
	static bool DeleteTypeLevel(uint16 id);
	static uint64 GetTypeLevelCreateTime(uint16 id);

	// ContextLevelMap
	static bool CreateNewContextLevel(uint16 id, const char* name, uint64 time = 0);
	static bool GetContextLevelName(uint16 id, char* name, uint32 maxSize);
	static bool GetContextLevelID(const char* name, uint16 &id);
	static bool DeleteContextLevel(const char* name);
	static bool DeleteContextLevel(uint16 id);
	static uint64 GetContextLevelCreateTime(uint16 id);

	// TopicMap
	static bool CreateNewTopic(uint8 id, const char* name);
	static bool GetTopicName(uint32 id, char* name, uint32 maxSize);
	static bool GetTopicID(const char* name, uint32 &id);
	static bool DeleteTopic(const char* name);
	static bool DeleteTopic(uint32 id);
	static uint64 GetTopicCreateTime(uint32 id);

	// NodeMap
	//static bool CreateNewNode(uint8 id, const char* name, uint64 address);
	//static uint64 GetNodeAddress(uint16 id);
	//static bool GetNodeID(uint64 address, uint16 &id);
	//static bool GetNodeName(uint16 id, char* name, uint32 maxSize);
	//static bool GetNodeID(const char* name, uint16 &id);
	//static bool DeleteNode(uint64 address);
	//static bool DeleteNode(uint16 id);
	//static bool DeleteNode(const char* name);
	//static uint64 GetNodeCreateTime(uint16 id);

	// CrankMap
	static bool CreateNewCrank(uint16 id, const char* name, const char* function, const char* libraryFilename, uint64 time = 0);
	static bool GetCrankName(uint16 id, char* name, uint32 maxSize);
	static bool GetCrankFunction(uint16 id, char* function, uint32 maxSize);
	static bool GetCrankLibraryFilename(uint16 id, char* libraryFilename, uint32 maxSize);
	static bool GetCrankID(const char* name, uint16 &id);
	static bool GetCrankScript(uint16 id, char* script, uint32 maxSize);
	static bool SetCrankScript(uint16 id, const char* script);
	static bool DeleteCrank(uint16 id);
	static bool DeleteCrank(const char* name);
	static uint64 GetCrankCreateTime(uint16 id);

	//// QueueMap
	//static bool CreateNewQueue(uint32 pageID, const char* name, uint32 &id);
	//static bool GetQueueName(uint32 id, char* name, uint32 maxSize);
	//static uint32 GetQueuePageID(uint32 id);
	//static bool GetQueueID(const char* name, uint32 &id);
	//static bool GetQueueID(uint32 pageID, uint32 &id);
	//static bool DeleteQueue(uint32 id);
	//static bool DeleteQueue(const char* name);
	//static uint64 GetQueueCreateTime(uint32 id);

	//// ProcessMap
	//static bool CreateNewProcess(const char* name, uint16 &id);
	//static bool GetProcessName(uint16 id, char* name, uint32 maxSize);
	//static bool GetProcessID(const char* name, uint16 &id);
	//static bool GetProcessQueueID(uint16 id, uint8 queueType, uint32& qid);
	//static uint8 GetProcessStatus(uint16 id, uint64& lastseen);
	//static bool GetProcessCommandLine(uint16 id, char* cmdline, uint32 maxSize);
	//static bool SetProcessQueueID(uint16 id, uint8 queueType, uint32 qid);
	//static bool SetProcessStatus(uint16 id, uint8 status);
	//static bool SetProcessCommandLine(uint16 id, const char* cmdline);
	//static uint16 GetProcessIDFromOSID(uint32 osid);
	//static uint32 GetProcessOSID(uint16 id);
	//static bool SetProcessOSID(uint16 id, uint32 osid);
	//static bool DeleteProcess(const char* name);
	//static bool DeleteProcess(uint16 id);
	//static uint64 GetProcessCreateTime(uint16 id);

	//// RequestMap
	//static RequestMapEntry* CreateAndLockNewRequest(uint32 from, uint32 to, uint32 &id);
	//static RequestMapEntry* GetAndLockRequestEntry(uint32 id);
	//static bool UnlockRequestMap();
	//static bool DeleteRequest(uint32 id);
	//static bool GetRequestCount(uint32& count);

protected:
//	static ProcessMapEntry* GetAndLockProcessEntry(uint16 id);
//	static bool UnlockProcessMap();
};



















template <typename T, typename ID, typename KEY>
class GenericMemoryMap {
public:
	// Generic MemoryMap
	static uint32 GetCount(char* data);
	static T* CreateEntry(char* data, ID id, const char* name);
	static T* GetEntry(char* data, ID id);
	static bool DeleteEntry(char* data, ID id);
	static uint64 GetEntryTime(char* data, ID id);
	static const char* GetEntryName(char* data, ID id, uint32& size);
	static ID GetEntryID(char* data, const char* name);
};



} // namespace cmlabs

#include "PsyTime.h"
#include "MemoryMaps.tpl.h"

#endif // _MEMORYMAPS_H_

	