const express = require("express");
const execSync = require('child_process').execSync;
var parser = require('xml2json');
const fs = require('fs');
var cors = require('cors');
const bodyParser = require("body-parser");
var mysql      = require('mysql2/promise');
const bluebird = require('bluebird');


const app = express();
app.use(cors());
const port = 3001;

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());


let conf = {
  connectionLimit : 10,
  host     : '127.0.0.1',
  user     : 'ds',
  password : 'EmcoAdmin!',
  database : 'modeler',
  Promise: bluebird
}


const jsn = require("./base.json");
const di = require("./di.json");
const ia = require("./ia.json");
const mach = require("./machinery.json");
const mt = require("./mt.json");

let ns_array = [];
let nsray = [jsn, di, ia, mach, mt];
/*nsray.push(jsn);
nsray.push(di);
nsray.push(ia);
nsray.push(mach);
nsray.push(mt);
*/

let type_ar = ['datatypes', 'objecttypes', 'referencetypes', 'variabletypes'];
let classes_ar = ['datatypes', 'objecttypes', 'referencetypes', 'variabletypes', 'objects', 'variables', 'methods'];
let child_refs = ['Organizes','HasComponent','HasProperty','HasAddIn','HasSubtype'];

/*
async function gen_query(sql, params){
  const connection = await mysql.createConnection(conf);
  const [results, ] = await connection.execute(sql, params);
  //console.log(results);
  return results;
}*/




async function translateNid(nid, m){ //Uni -> local
	try{
		let obj = {
			idx: 0,
			ns: 0,
			ident: '0',
			combi: '',
			p1: '',
			p2:''
		}
		/*
		let obj = {
			ident_all:"",
			ident:"",
			ns_local: 0,
			combi_local: "",
			ns_old: 0,
			combi_old: "",
			ns_new: 0,
			combi_new: ""
		}*/
		if(nid.includes('ns=')){
			const nodeid = nid.split(";");
			obj.p1 = nodeid[0];
			obj.p2 = nodeid[1];
			const n1 = nodeid[0].split("=");
			obj.ns = parseInt(n1[1]);
			const n2 = nodeid[1].split("=");
			obj.ident = n2[1];
						
			var command = "SELECT nsurl FROM ns"+m+"depends WHERE nsindex='"+obj.ns+"';";
			var ret = await pool.query(command);
			command = "SELECT nsindex FROM namespaces WHERE nsurl='"+ret[0][0].nsurl+"';";
			ret = await pool.query(command);
			obj.idx = parseInt(ret[0][0].nsindex);
			obj.combi = "ns=1;"+nodeid[1];
		}else{
			const n1 = nid.split("=");
			obj.ident = n1[1];
			obj.combi = nid;
			obj.p2 = nid;
		}
		return obj;
	}catch(err){
		console.log(err);
	}
}

async function newNid(nid, i){ //Uni -> whatever is needed, global in i
	try{
		let obj = {
			ident_all:"",
			ident:"",
			ns: i,
			ns_local: 0,
			combi_local: "",
			ns_uni: 0,
			combi_uni: nid
		}
		if(nid.includes('ns=')){
			const nodeid = nid.split(";");
			obj.ident_all = nodeid[1];
			const n1 = nodeid[0].split("=");
			const n2 = nodeid[1].split("=");
			obj.ident = n2[1];
			obj.ns_uni = parseInt(n1[1]);
			var command = "SELECT nsurl FROM namespaces WHERE nsindex='"+n1[1]+"';";
			var ret = await pool.query(command);
			const ul = parseInt(ret[0][0].nsurl);
			command = "SELECT nsindex FROM ns"+i+"depends WHERE nsurl='"+ul+"';";
			ret = await pool.query(command);
			obj.ns_local = parseInt(ret[0][0].nsindex);
			obj.combi_local = "ns="+obj.ns_local+";"+obj.ident_all;
		}else{
			const n1 = nid.split("=");
			obj.ident = n1[1];
			obj.ident_all = nid;
			obj.combi_local = nid;
			obj.combi_uni = nid;

		}
		return obj;
	}catch(err){
		console.log(err);
	}
}



async function getUniNid(nid, m){ //local -> Uni
	try{
		let obj = {
			ident_all:"",
			ident:"",
			ns: parseInt(m),
			ns_local: 0,
			combi_local: nid,
			ns_uni: 0,
			combi_uni: ""
		}
		if(nid.includes('ns=')){
			const nodeid = nid.split(";");
			obj.ident_all = nodeid[1];
			const n1 = nodeid[0].split("=");
			obj.ns_local = parseInt(n1[1]);
			const n2 = nodeid[1].split("=");
			obj.ident = n2[1];
						
			var command = "SELECT nsurl FROM ns"+m+"depends WHERE nsindex='"+obj.ns_local+"';";
			var ret = await pool.query(command);
			command = "SELECT nsindex FROM namespaces WHERE nsurl='"+ret[0][0].nsurl+"';";
			ret = await pool.query(command);
			obj.ns_uni = parseInt(ret[0][0].nsindex);
			obj.combi_uni = "ns="+obj.ns_uni+";"+obj.ident_all;
			
		}else{
			const n1 = nid.split("=");
			obj.ident = n1[1];
			obj.ident_all = nid;
			obj.combi_uni = nid;
		}
		return obj;
	}catch(err){
		console.log(err);
	}

}

async function getLocalNid(nid, m){ // Uni -> local
	try{
		let obj = {
			ident_all:"",
			ident:"",
			ns: 0,
			ns_local: 1,
			combi_local: "",
			ns_uni: m,
			combi_uni: ""
		}
		if(nid.includes('ns=')){
			const nodeid = nid.split(";");
			obj.ident_all = nodeid[1];
			const n1 = nodeid[0].split("=");
			obj.ns = obj.ns_uni;
			const n2 = nodeid[1].split("=");
			obj.ident = n2[1];
			obj.combi_local = "ns=1;"+obj.ident_all;
			obj.combi_uni = "ns="+m+";"+obj.ident_all;
			
			
		}else{
			const n1 = nid.split("=");
			obj.ident = n1[1];
			obj.ident_all = nid;
			obj.combi_local = nid;
	
		}
		return obj;
	}catch(err){
		console.log(err);
	}
}

function database_connection() {
pool = mysql.createPool(conf);
pool.getConnection(function(err, connection) {
    if(err) {
        logger.error('[ERROR] Connecting to database "' + err.toString() + '"');
        setTimeout(function() { database_connection(); }, 2500);
    }
    else
    {
        pool.query('SET NAMES utf8');
        pool.query('SET CHARACTER SET utf8');
        logger.trace('[INFO] Connected to database and set utf8!');
    }
})};

database_connection();


function inverse(dev){
	if("IsForward" in dev){
		if(dev.IsForward === "false"){
			return true;
			
		}else{
			return false;
			}
	}else{
		return false;
	}
}

function forward(dev){
	var b = true;
	if("IsForward" in dev){
		if(dev.IsForward === "false"){
			b = false;
			}
		}else{
			b = true;
			}
	return b;	
}

function sortNS(files){
	let nsets = [];
	
	for(let x = 0; x<files.length; x++){
		if("RequiredModel" in files[x].UANodeSet.Models.Model){
			if(Array.isArray(files[x].UANodeSet.Models.Model.RequiredModel)){
				var len = files[x].UANodeSet.Models.Model.RequiredModel.length;
				for(let y = 0; y < len; y++){
						files[x].UANodeSet.Models.Model.RequiredModel[y]
				}
			}else{
				
			}
		}else{
			nsets.push(files[x].UANodeSet.Models.Model.ModelUri);
		}
	}
}


function get_Children(jsnob, nid, ret_obj){
	const entities = ['UAObjectType','UAObject','UAVariableType','UAVariable', 'UADataType', 'UAReferenceType', 'UAMethod'];
	const set = jsnob.UANodeSet;
	for(let y = 0; y< entities.length; y++){
		if(entities[y] in set){
			try{
				const entry = set[entities[y]];
				if(Array.isArray(entry)){
					for (let i = 0; i < entry.length;i++){
						if(Object.keys(entry[i].References).length === 0){

						}else{
							if(Array.isArray(entry[i].References.Reference)){
								for (let x = 0; x < entry[i].References.Reference.length;x++){
									if(entry[i].References.Reference[x].$t === nid){
										if(inverse(entry[i].References.Reference[x])){
											let zobj= overwriteNode(entry[i],  nid, entities[y],  getIndexArray(jsnob));
											if(!checkDouble(zobj,ret_obj)){
												ret_obj.push(zobj);
											}
										}
									}
								 }
							}else{
									if(entry[i].References.Reference.$t === nid){
										if(inverse(entry[i].References.Reference)){
											let zobj= overwriteNode(entry[i], nid, entities[y], getIndexArray(jsnob));
											if(!checkDouble(zobj,ret_obj)){
												ret_obj.push(zobj);
											}
										}
									}
							}
						}
					}
				}else{
					if(Object.keys(entry.References).length === 0){

					}else{
					if(Array.isArray(entry.References.Reference)){
						for (let x = 0; x < entry.References.Reference.length;x++){
							if(entry.References.Reference[x].$t === nid){
								if(inverse(entry.References.Reference[x])){
								let zobj= overwriteNode(entry, nid, entities[y], getIndexArray(jsnob));
								if(!checkDouble(zobj,ret_obj)){
										ret_obj.push(zobj);
									}
								}
							}
						}
					}else{
						if(entry.References.Reference.$t === nid){
							if(inverse(entry.References.Reference)){
							let zobj= overwriteNode(entry, nid, entities[i], getIndexArray(jsnob));
								if(!checkDouble(zobj,ret_obj)){
										ret_obj.push(zobj);
									}
							}
						}
						}		
					}
				}
			}catch(err){
				console.log(err);
			}
		}
	}
}

function getAllChildren(nid, ret_obj){
	for(let ix = 0; ix < ns_array.length; ix++){
		get_Children(ns_array[ix][0], nid, ret_obj);
	}
}


function getIndexObj(jsnob, ns){
	var uri = ns.UANodeSet.Models.Model.ModelUri;
	if(uri == "http://opcfoundation.org/UA/"){
		return 0;
	}
	console.log(uri);
	let uris = {};
	if(jsnob.UANodeSet.NamespaceUris != undefined){
		uris = jsnob.UANodeSet.NamespaceUris.Uri;
		console.log(uris);
	}else{
		return 0;
	}
	for(let i = 0; i < uris.length; i++){
		console.log(uris[i]);
		if(uris[i] == uri){
			return i+1;
		}
	}
	return undefined;	
}

function getIndexName(jsnob, name){
	if(name == "http://opcfoundation.org/UA/"){
		return 0;
	}
	let uris = {};
	if(jsnob.UANodeSet.NamespaceUris != undefined){
		uris = jsnob.UANodeSet.NamespaceUris.Uri;
	}else{
		return 0;
	}
	for(let i = 0; i < uris.length; i++){
		if(uris[i] == name){
			return i+1;
		}
	}
	return undefined;	
}

function getIndexArray(tobj){
	for(let i = 0; i < ns_array.length;i++){
		console.log(ns_array[i][1]);
		if(tobj.UANodeSet.Models.Model.ModelUri === ns_array[i][0].UANodeSet.Models.Model.ModelUri){
				return i;
		}	
	}
	return undefined;	
}



function getNode(jsnob, ns, id){
	let uris = {};
	var ns_uri = '';
	if(jsnob.UANodeSet.NamespaceUris){
		uris = jsnob.UANodeSet.NamespaceUris.Uri;
		ns_uri = uris[ns-1];
	}
	for(let i = 0; i < ns_array.length; i++){
		if(ns_array[i][0].UANodeSet.Models.Model.ModelUri == ns_uri){
			return i;
		}
	}
	return -1;	
}

function overwriteNode(nobj, nid, nc, ns){
	var nclass = "";
	switch(nc){
		case "UAObjectType": 
		case "UAObject":
		case "UAVariableType":
		case "UADataType":
		case "UAReferenceType": nclass = "Object"; break;
		case "UAVariable": nclass = "Variable"; break;
		case "UAMethod": nclass = "Method"; break;
		default: nclass = "Object";
	}
	const node = {
		id:nobj.NodeId,
		text:nobj.DisplayName,
		children: true,
		data:{
			browsename: nobj.BrowseName,
			namespace: ns,
			elementclass: nc,
			nodeclass: nclass,
			parentNode: nid,
			parentid: "ParentNodeId" in nobj ? nobj.ParentNodeId : null,
			description: "Description" in nobj ? nobj.Description : null,
			notifier: "EventNotifier" in nobj ? nobj.EventNotifier : null, //Object
			isabstract: "IsAbstract" in nobj ? nobj.IsAbstract : null, //ObjectType
			datatype: "DataType" in nobj ? nobj.DataType : null, //Variable
			value: "Value" in nobj ? nobj.Value : null, //Variable
			arraydimensions: "ArrayDimensions" in nobj ? nobj.ArrayDimensions : null, //Variable
			references: "References" in nobj ? nobj.References : null
		}
		
	}
	return node;
}


function searchNode(id){
	const entities = ['UAObjectType','UAObject','UAVariableType','UAVariable', 'UADataType', 'UAReferenceType', 'UAMethod']; //7
	var nid = "";
	var jsnob = {};
	if(id.includes("ns=")){
		var ns = id.substring(id.length - 4);
		const ns1 = ns.split(";");
		var nsidx = parseInt(ns1[0]);
		jsnob = ns_array[nsidx][0];
	}else{
		nid = id;
		jsnob = ns_array[0][0];
	}
	const set = jsnob.UANodeSet;
	for(let i = 0; i< entities.length; i++){
		if(entities[i] in set){
			console.log(set.Models.Model.ModelUri+" has a "+entities[i]);
			if(Array.isArray(set[entities[i]])){
				for(let x = 0; x < set[entities[i]].length;x++){
					if(set[entities[i]][x].NodeId === nid){
						let nobj = set[entities[i]][x];
						const node = overwriteNode(nobj, null, entities[i], getIndexArray(jsnob));
						return node;
					}
				}
			}
		}
	}
	return null;
}



function p2json(name, shorty){
	try{
	const nn = name+".xml";
	var nnn = shorty+".json";

	fs.readFile( nn, function(err, data){
	//fs.readFile( "Opc.Ua.NodeSet2.xml", function(err, data){
		let jsn = parser.toJson(data);
		fs.writeFileSync(nnn, jsn);
	});
	}catch(err){
		console.log('not work');}

}

/*

function listObjType(){
	var keys = [];
	console.log("ObjectTypes:");
	let obj = jsn.UANodeSet.UAObjectType; //base
		var sz = obj.length;
		console.log(sz);
		for(let i = 0; i < sz; i++){
			let arr = Object.keys(obj[i]);
			for(let x = 0; x < arr.length; x++){
				if(!keys.includes(arr[x])){
					keys.push(arr[x]);
				}
			}
		}
	obj = di.UANodeSet.UAObjectType; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = ia.UANodeSet.UAObjectType; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = mach.UANodeSet.UAObjectType; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = mt.UANodeSet.UAObjectType; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	console.log(keys);
}

listObjType();

function listObj(){
	var keys = [];
	console.log("Objects:");
	let obj = jsn.UANodeSet.UAObject; //base
		var sz = obj.length;
		console.log(sz);
		for(let i = 0; i < sz; i++){
			let arr = Object.keys(obj[i]);
			for(let x = 0; x < arr.length; x++){
				if(!keys.includes(arr[x])){
					keys.push(arr[x]);
				}
			}
		}
	obj = di.UANodeSet.UAObject; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = ia.UANodeSet.UAObject; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = mach.UANodeSet.UAObject; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = mt.UANodeSet.UAObject; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	console.log(keys);
}

listObj();

function listVar(){
	var keys = [];
	console.log("Variables:");
	let obj = jsn.UANodeSet.UAVariable; //base
		var sz = obj.length;
		console.log(sz);
		for(let i = 0; i < sz; i++){
			let arr = Object.keys(obj[i]);
			for(let x = 0; x < arr.length; x++){
				if(!keys.includes(arr[x])){
					keys.push(arr[x]);
				}
			}
		}
	obj = di.UANodeSet.UAVariable; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = ia.UANodeSet.UAVariable; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = mach.UANodeSet.UAVariable; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = mt.UANodeSet.UAVariable; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	console.log(keys);
}

listVar();

function listVarTypes(){
	var keys = [];
	console.log("VariableTypes:");
	let obj = jsn.UANodeSet.UAVariableType; //base
		var sz = obj.length;
		console.log(sz);
		for(let i = 0; i < sz; i++){
			let arr = Object.keys(obj[i]);
			for(let x = 0; x < arr.length; x++){
				if(!keys.includes(arr[x])){
					keys.push(arr[x]);
				}
			}
		}
	obj = di.UANodeSet.UAVariableType; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = ia.UANodeSet.UAVariableType; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = mach.UANodeSet.UAVariableType; //base
	if(obj !== undefined){
	if(Array.isArray(obj)){
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}}else{
		let arr = Object.keys(obj);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	}
	obj = mt.UANodeSet.UAVariableType; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	console.log(keys);
}

listVarTypes();


function listMethod(){
	var keys = [];
	console.log("Methods:");
	let obj = jsn.UANodeSet.UAMethod; //base
		var sz = obj.length;
		console.log(sz);
		for(let i = 0; i < sz; i++){
			let arr = Object.keys(obj[i]);
			for(let x = 0; x < arr.length; x++){
				if(!keys.includes(arr[x])){
					keys.push(arr[x]);
				}
			}
		}
	obj = di.UANodeSet.UAMethod; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = ia.UANodeSet.UAMethod; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = mach.UANodeSet.UAMethod; //base
	if(obj !== undefined){
	if(Array.isArray(obj)){
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}}else{
		let arr = Object.keys(obj);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}}
	obj = mt.UANodeSet.UAMethod; //base
	if(obj !== undefined){
	if(Array.isArray(obj)){
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}}else{
		let arr = Object.keys(obj);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}}
	console.log(keys);
}

listMethod();

function listDataType(){
	var keys = [];
	console.log("DataType:");
	let obj = jsn.UANodeSet.UADataType; //base
		var sz = obj.length;
		console.log(sz);
		for(let i = 0; i < sz; i++){
			let arr = Object.keys(obj[i]);
			for(let x = 0; x < arr.length; x++){
				if(!keys.includes(arr[x])){
					keys.push(arr[x]);
				}
			}
		}
	obj = di.UANodeSet.UADataType; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = ia.UANodeSet.UADataType; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = mach.UANodeSet.UADataType; //base
	if(obj !== undefined){
	if(Array.isArray(obj)){
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}}else{
		let arr = Object.keys(obj);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}}
	obj = mt.UANodeSet.UADataType; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	console.log(keys);
}

listDataType();

function listRefType(){
	var keys = [];
	console.log("ReferenceTypes:");
	let obj = jsn.UANodeSet.UAReferenceType; //base
		var sz = obj.length;
		console.log(sz);
		for(let i = 0; i < sz; i++){
			let arr = Object.keys(obj[i]);
			for(let x = 0; x < arr.length; x++){
				if(!keys.includes(arr[x])){
					keys.push(arr[x]);
				}
			}
		}
	obj = di.UANodeSet.UAReferenceType; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = ia.UANodeSet.UAReferenceType; //base
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}
	obj = mach.UANodeSet.UAReferenceType; //base
	if(obj !== undefined){
	if(Array.isArray(obj)){
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}}else{
		let arr = Object.keys(obj);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}}
	obj = mt.UANodeSet.UAReferenceType; //base
	if(obj !== undefined){
	if(Array.isArray(obj)){
	sz = obj.length;
	console.log(sz);
	for(let i = 0; i < sz; i++){
		let arr = Object.keys(obj[i]);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}}else{
		let arr = Object.keys(obj);
		for(let x = 0; x < arr.length; x++){
			if(!keys.includes(arr[x])){
				keys.push(arr[x]);
			}
		}
	}}
	console.log(keys);
}

listRefType();

*/

let arref = [];

async function getThisNodeAttribute(ix, nid, classname, attr){
	try{
		var res = "";
		
 //0/i=84/UAObject
		var nnid = await getLocalNid(nid);
		var command = "SELECT * FROM ns"+ix+""+classname+" WHERE nodeid='"+nnid.combi_local+"';";
		var ret = await pool.query(command);

		if(ret[0].length !== 0){
			res = ret[0][0][attr];
			return res;
		}
	
		return res;
	}catch(err){
		console.log(err);
	}
}

async function getThisNode(ix, nid, classname){
	try{
		var res = "";
		var nnid = await getLocalNid(nid, ix);
		var command = "SELECT * FROM ns"+nnid.ns_uni+""+classname+" WHERE nodeid='"+nnid.combi_local+"';";
		var ret = await pool.query(command);
		var resp = ret[0][0];
		var flag_ch = true;
		/*var val1 = await getChildrenSql(ix, nid);
		if(val1.length == 0){
			flag_ch = false;
		}
		*/
		if(ret[0].length !== 0){
			var l = await getUniNid(resp.nodeid, nnid.ns_uni);
			
			obj0 = {
				id: l.combi_uni,
				text: resp.name,
				data: ret[0][0],
				children: flag_ch	
			};
			
			obj0.data.nsindex = l.ns_uni;
			res = obj0;
			return res;
		}
	
		return res;
	}catch(err){
		console.log(err);
	}
}

async function getChildrenSql(ix, nid){ //Uni nodeid -> 4/ns=4;i=131
	try{
		let res = [];
		for(let i = ix; i < nsray.length; i++){
			var obj = await newNid(nid, i);
			var command = "SELECT nodeidorigin FROM ns"+i+"references WHERE target='"+obj.combi_local+"' AND isforward='false';";
			var ret = await pool.query(command);
				const iterator = ret[0].values();
				for (const value of iterator) {
					var bb = await getUniNid(value.nodeidorigin, i)
					var nc = "";
					for(let j = 0; j < classes_ar.length; j++){
						if(bb.ns_uni !== 0){
							command = "SELECT nodeclass FROM ns"+bb.ns_uni+""+classes_ar[j]+" WHERE nodeid='ns=1;"+bb.ident_all+"';";
							ret = await pool.query(command);
							if(ret[0].length !== 0){
								nc = ret[0][0].nodeclass;
								res.push([bb.combi_uni, bb.ns_uni, nc]);
							}	
						}else{
							command = "SELECT nodeclass FROM ns0"+classes_ar[j]+" WHERE nodeid='"+bb.ident_all+"';";
							ret = await pool.query(command);		
							if(ret[0].length !== 0){
								nc = ret[0][0].nodeclass;
								res.push([bb.combi_uni, bb.ns_uni, nc]);
							}		
						}
					}	
				}
			//}
		}
		return res;
	}catch(err){
		console.log(err);
	}
}


async function checkRefs(obj, nsix, url){
	try{
		var nid = obj.NodeId;
		var idx1 = 0;
		if(nid.includes('ns=')){
			var iy = nid.indexOf(';');
			var ns = nid.substring(3,iy);
			idx1 = parseInt(ns);
		}
		// 1 oder 0
		// nsix = index bei den nodesets
		
		var ret = {};
		if(obj['References']){
			let refs = obj.References.Reference;
			if(Array.isArray(refs)){
				for(let i = 0; i < refs.length; i++){
					var elem = refs[i];
					var nid_t = "";
					if(nid.includes('i=')){
						nid_t = 'Numeric';
					}else if(nid.includes('s=')){
						nid_t = 'String';
					}
					var nst = 0;
					var target = "";
					var t_new = "";
					if(elem['$t']){
						target = elem['$t'];
						t_new = await translateNid(target, nsix);
						nst = t_new.idx || 0;
					}
					var command = "INSERT INTO ns"+nsix+"references(nodeidorigin, nodeidtype, nsindex, nsurl, referencetype, isforward, target, ns_target) VALUES ('"+nid+"', '"+nid_t+"', '"+idx1+"', '"+url+"', '"+elem['ReferenceType']+"', '"+elem['IsForward']+"', '"+target+"', '"+nst+"');";
					var ret = await pool.query(command);
				}
			}else{
				var elem = refs;
				var nid_t = "";
				if(nid.includes('i=')){
					nid_t = 'Numeric';
				}else if(nid.includes('s=')){
					nid_t = 'String';
				}
				var nst = 0;
				var target = "";
				var t_new = "";
				if(elem['$t']){
					target = elem['$t'];
						t_new = await translateNid(target, nsix);
						nst = t_new.idx || 0;
				}
				var command = "INSERT INTO ns"+nsix+"references(nodeidorigin, nodeidtype, nsindex, nsurl, referencetype, isforward, target, ns_target) VALUES ('"+nid+"', '"+nid_t+"', '"+idx1+"', '"+url+"', '"+elem['ReferenceType']+"', '"+elem['IsForward']+"', '"+target+"', '"+nst+"');";
				var ret = await pool.query(command);
			}
		}
	}catch(err){
		console.log(err);
		}
}


async function getTypeDef(nid, ix){
	try{
		let obj = await translateNid(nid, ix);
		for(let z = 0; z < type_ar.length; z++){
			var command = "SELECT name FROM ns"+obj.idx+""+type_ar[z]+" WHERE nodeid='"+obj.combi+"';";
			var ret = await pool.query(command);
			console.log(ret[0][0]);
			if(ret[0].length === 0){
			}else{
				return ret[0][0].name;
			}
		}
		return "?";
		
	}catch(err){
		console.log(err);
	}
}

async function getDataType(nid, ix){
	try{
		var obj = await translateNid(nid, ix);
		console.log(obj);
		var command = "SELECT name FROM ns"+obj.idx+"datatypes WHERE nodeid='"+obj.combi+"';";
		console.log(command);
		var ret = await pool.query(command);		
		return ret[0][0].name;

	}catch(err){
		console.log(err);
	}
}

async function getParentRef(entry, ix){
	try{
		let pnode = {
			pnid: "",
			pref: "",
			pinv: "false"
		}
		if(entry['ParentNodeId']){
			pnode.pnid = entry['ParentNodeId'];
		}
		if(entry['References']){
			let refs = entry.References.Reference;
			if(Array.isArray(refs)){
				for(let d = 0; d < refs.length; d++){
					var command = "SELECT DISTINCT target,referencetype FROM ns"+ix+"references WHERE nodeidorigin='"+entry['NodeId']+"' AND referencetype='"+refs[d]['ReferenceType']+"' AND isforward LIKE 'fal%';";
					var ret = await pool.query(command);
					if(ret[0].length === 0){
						continue;
					}else{
						if(pnode.pnid === ret[0][0].target){
							pnode.pref = ret[0][0].referencetype;
							pnode.pinv = "false";
							
								console.log(ret);
							
						}else{
							pnode.pnid = ret[0][0].target;
							pnode.pref = ret[0][0].referencetype;
							pnode.pinv = "true";
						}
					}
				}
			}else{
				var command = "SELECT DISTINCT target,referencetype FROM ns"+ix+"references WHERE nodeidorigin='"+entry['NodeId']+"' AND referencetype='"+refs['ReferenceType']+"' AND isforward LIKE 'fal%';";
				var ret = await pool.query(command);
				if(ret[0].length === 0){
				
				}else{
					if(pnode.pnid === ret[0][0].target){
						pnode.pref = ret[0][0].referencetype;
						pnode.pinv = "false";
					}else{
						pnode.pnid = ret[0][0].target;
						pnode.pref = ret[0][0].referencetype;
						pnode.pinv = "true";
					}
				}
			}
		}
		return pnode;
	}catch(err){
		console.log(err);
	}
}


async function createNamespace(m){
	try{
		var command = "CREATE TABLE IF NOT EXISTS ns"+m+"objects(id INT AUTO_INCREMENT, nodeid VARCHAR(300) NOT NULL UNIQUE, nodeidtype VARCHAR(100) NOT NULL, name VARCHAR(300) NOT NULL, nodeclass VARCHAR(50) DEFAULT 'Object', nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', displayname VARCHAR(300) NOT NULL, browsename VARCHAR(300) NOT NULL, description VARCHAR(300), eventnotifier INT DEFAULT NULL, typedefinition VARCHAR(300) NOT NULL, parentid VARCHAR(300) DEFAULT '#', parentreference VARCHAR(300), parentinverse VARCHAR(10), documentation VARCHAR(300), comment VARCHAR(300), PRIMARY KEY(id));";
		var ret = await pool.query(command);
		command = "CREATE TABLE IF NOT EXISTS ns"+m+"objecttypes(id INT AUTO_INCREMENT, nodeid VARCHAR(300) NOT NULL UNIQUE, nodeidtype VARCHAR(100) NOT NULL, name VARCHAR(300) NOT NULL, nodeclass VARCHAR(50) DEFAULT 'ObjectType', nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', displayname VARCHAR(300) NOT NULL, browsename VARCHAR(300) NOT NULL, description VARCHAR(300), isabstract VARCHAR(10), parentid VARCHAR(300) DEFAULT '#', parentreference VARCHAR(300), parentinverse VARCHAR(10), comment VARCHAR(300), documentation VARCHAR(300), PRIMARY KEY(id));";
		ret = await pool.query(command);
		command = "CREATE TABLE IF NOT EXISTS ns"+m+"variables(id INT AUTO_INCREMENT, nodeid VARCHAR(300) NOT NULL UNIQUE, nodeidtype VARCHAR(100) NOT NULL, name VARCHAR(300) NOT NULL, nodeclass VARCHAR(50) DEFAULT 'Variable', nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', displayname VARCHAR(300) NOT NULL, browsename VARCHAR(300) NOT NULL, description VARCHAR(300), modellingrule VARCHAR(100) DEFAULT 'Optional', datatype VARCHAR(300) NOT NULL, typedefinition VARCHAR(300) NOT NULL, value VARCHAR(500) DEFAULT NULL, valuerank INT DEFAULT NULL, arraydimensions INT, accesslevel INT DEFAULT NULL, accesslevelex INT DEFAULT NULL, historizing VARCHAR(10), minsamplinginterval INT DEFAULT 500, releasestatus VARCHAR(300), parentid VARCHAR(300) DEFAULT '#', parentreference VARCHAR(300), parentinverse VARCHAR(10), documentation VARCHAR(300), comment VARCHAR(300), PRIMARY KEY(id));";
		ret = await pool.query(command);
		command = "CREATE TABLE IF NOT EXISTS ns"+m+"variabletypes(id INT AUTO_INCREMENT, nodeid VARCHAR(300) NOT NULL UNIQUE, nodeidtype VARCHAR(100) NOT NULL, name VARCHAR(300) NOT NULL, nodeclass VARCHAR(50) DEFAULT 'VariableType', nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', displayname VARCHAR(300) NOT NULL, browsename VARCHAR(300) NOT NULL, description VARCHAR(300), datatype VARCHAR(300) NOT NULL, value VARCHAR(500) DEFAULT NULL, valuerank INT DEFAULT NULL, arraydimensions INT, isabstract VARCHAR(10), parentid VARCHAR(300) DEFAULT '#', parentreference VARCHAR(300), parentinverse VARCHAR(10), documentation VARCHAR(300), comment VARCHAR(300), PRIMARY KEY(id));";
		ret = await pool.query(command);
		command = "CREATE TABLE IF NOT EXISTS ns"+m+"methods(id INT AUTO_INCREMENT, nodeid VARCHAR(300) NOT NULL UNIQUE, nodeidtype VARCHAR(100) NOT NULL, name VARCHAR(300) NOT NULL, nodeclass VARCHAR(50) DEFAULT 'Method', nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', displayname VARCHAR(300) NOT NULL, browsename VARCHAR(300) NOT NULL, description VARCHAR(300), modellingrule VARCHAR(100) DEFAULT 'Optional', executable INT DEFAULT 1, parentreference VARCHAR(300), parentid VARCHAR(300) DEFAULT '#', methoddeclarationid VARCHAR(300), parentinverse VARCHAR(10), documentation VARCHAR(300), comment VARCHAR(300), PRIMARY KEY(id));";		
		ret = await pool.query(command);
		command = "CREATE TABLE IF NOT EXISTS ns"+m+"datatypes(id INT AUTO_INCREMENT, nodeid VARCHAR(300) NOT NULL UNIQUE, nodeidtype VARCHAR(100) NOT NULL, name VARCHAR(300) NOT NULL, nodeclass VARCHAR(50) DEFAULT 'DataType', nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', displayname VARCHAR(300) NOT NULL, browsename VARCHAR(300) NOT NULL, description VARCHAR(300), isabstract VARCHAR(10), parentid VARCHAR(300) DEFAULT '#', parentreference VARCHAR(300), parentinverse VARCHAR(10), definition VARCHAR(300), releasestatus VARCHAR(300), documentation VARCHAR(300), comment VARCHAR(300), PRIMARY KEY(id));";
		ret = await pool.query(command);
		command = "CREATE TABLE IF NOT EXISTS ns"+m+"referencetypes(id INT AUTO_INCREMENT, nodeid VARCHAR(300) NOT NULL UNIQUE, nodeidtype VARCHAR(100) NOT NULL, name VARCHAR(300) NOT NULL, inversename VARCHAR(300), symmetric VARCHAR(10) DEFAULT 'TBD', nodeclass VARCHAR(50) DEFAULT 'ReferenceType', nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', displayname VARCHAR(300) NOT NULL, browsename VARCHAR(300) NOT NULL, description VARCHAR(300), isabstract VARCHAR(10) DEFAULT 'TBD', parentid VARCHAR(300) DEFAULT '#', parentreference VARCHAR(300), parentinverse VARCHAR(10), documentation VARCHAR(300), comment VARCHAR(300), PRIMARY KEY(id));";
		ret = await pool.query(command);
		command = "CREATE TABLE IF NOT EXISTS ns"+m+"references(id INT AUTO_INCREMENT, nodeidorigin VARCHAR(300) NOT NULL, nodeidtype VARCHAR(100) NOT NULL, nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', referencetype VARCHAR(100) NOT NULL, isforward VARCHAR(10) DEFAULT 'true', target VARCHAR(300), t_nidt VARCHAR(100), ns_target INT DEFAULT NULL, comment VARCHAR(300), PRIMARY KEY(id));";
		ret = await pool.query(command);
	}catch(err){
	console.log(err);
	}
}

async function createObj(m){
	try{
		var command = "CREATE TABLE IF NOT EXISTS ns"+m+"objects(id INT AUTO_INCREMENT, nodeid VARCHAR(300) NOT NULL UNIQUE, nodeidtype VARCHAR(100) NOT NULL, name VARCHAR(300) NOT NULL, nodeclass VARCHAR(50) DEFAULT 'Object', nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', displayname VARCHAR(300) NOT NULL, browsename VARCHAR(300) NOT NULL, description VARCHAR(300), eventnotifier INT DEFAULT NULL, typedefinition VARCHAR(300) NOT NULL, parentid VARCHAR(300) DEFAULT '#', parentreference VARCHAR(300), parentinverse VARCHAR(10), documentation VARCHAR(300), comment VARCHAR(300), PRIMARY KEY(id));";
			var ret = await pool.query(command);
			var url = nsray[m].UANodeSet.Models.Model.ModelUri;
			let obj = nsray[m].UANodeSet.UAObject;
			if(nsray[m].UANodeSet.UAObject){
				if(Array.isArray(obj)){
					var sz = obj.length;
					for(let i = 0; i < sz; i++){
						var entry = obj[i];
						var nid = entry['NodeId'];
						await checkRefs(entry, m, url);
						var idx = 0;
						if(nid.includes('ns=')){
							var ix = nid.indexOf(';');
							var ns = nid.substring(3,ix);
							idx = parseInt(ns);
						}
						var nid_t = "";
						if(nid.includes('i=')){
							nid_t = 'Numeric';
						}else if(nid.includes('s=')){
							nid_t = 'String';
						}
						var eventnot = 0;
						if(entry['EventNotifier']){
							eventnot = parseInt(entry['EventNotifier']);
						}
						var tt = await getTypeDef(entry['NodeId'], m);
						let pnode = await getParentRef(entry, m);
						
						command = "INSERT INTO ns"+m+"objects(nodeid, nodeidtype, nsindex, nsurl, name, displayname, browsename, parentid, parentreference, parentinverse, typedefinition, description, eventnotifier, documentation) VALUES ('"+entry['NodeId']+"', '"+nid_t+"', '"+idx+"', '"+url+"', '"+entry['DisplayName']+"', '"+entry['DisplayName']+"', '"+entry['BrowseName']+"', '"+pnode.pnid+"', '"+pnode.pref+"', '"+pnode.pinv+"', '"+tt+"','"+entry['Description']+"', '"+eventnot+"', '"+entry['Documentation']+"');";
						ret = pool.query(command);
					}
					
				}else{
					var entry = obj;
					var nid = entry['NodeId'];
					var idx = 0;
					await checkRefs(entry, m, url);
					if(nid.includes('ns=')){
						var ix = nid.indexOf(';');
						var ns = nid.substring(3,ix);
						idx = parseInt(ns);
					}
					var nid_t = "";
					if(nid.includes('i=')){
						nid_t = 'Numeric';
					}else if(nid.includes('s=')){
						nid_t = 'String';
					}
					var eventnot = 0;
					if(entry['EventNotifier']){
						eventnot = parseInt(entry['EventNotifier']);
					}
					var tt = await getTypeDef(entry['NodeId'], m);
					let pnode = await getParentRef(entry, m);
					command = "INSERT INTO ns"+m+"objects(nodeid, nodeidtype, nsindex, nsurl, name, displayname, browsename, parentid, parentreference, parentinverse, typedefinition, description, eventnotifier, documentation) VALUES ('"+entry['NodeId']+"', '"+nid_t+"', '"+idx+"', '"+url+"', '"+entry['DisplayName']+"', '"+entry['DisplayName']+"', '"+entry['BrowseName']+"', '"+pnode.pnid+"', '"+pnode.pref+"', '"+pnode.pinv+"', '"+tt+"','"+entry['Description']+"', '"+eventnot+"', '"+entry['Documentation']+"');";
					ret = pool.query(command);
				}
			}
	}catch(err){
		console.log(err);
	}
	
}

async function createObjTypes(m){
	try{
		var command = "CREATE TABLE IF NOT EXISTS ns"+m+"objecttypes(id INT AUTO_INCREMENT, nodeid VARCHAR(300) NOT NULL UNIQUE, nodeidtype VARCHAR(100) NOT NULL, name VARCHAR(300) NOT NULL, nodeclass VARCHAR(50) DEFAULT 'ObjectType', nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', displayname VARCHAR(300) NOT NULL, browsename VARCHAR(300) NOT NULL, description VARCHAR(300), isabstract VARCHAR(10), parentid VARCHAR(300) DEFAULT '#', parentreference VARCHAR(300), parentinverse VARCHAR(10), comment VARCHAR(300), documentation VARCHAR(300), PRIMARY KEY(id));";
		var ret = await pool.query(command);
		let obj = nsray[m].UANodeSet.UAObjectType;
		var url = nsray[m].UANodeSet.Models.Model.ModelUri;
		if(nsray[m].UANodeSet.UAObjectType){
			if(Array.isArray(obj)){
				var sz = obj.length;
				for(let i = 0; i < sz; i++){
					var entry = obj[i];
					var nid = entry['NodeId'];
					var idx = 0;
					if(nid.includes('ns=')){
						var ix = nid.indexOf(';');
						var ns = nid.substring(3,ix);
						idx = parseInt(ns);
					}
					await checkRefs(entry, m, url);
					var nid_t = "";
					if(nid.includes('i=')){
						nid_t = 'Numeric';
					}else if(nid.includes('s=')){
						nid_t = 'String';
					}
					var isabstr = "TBD";
					if(entry['IsAbstract']){
						isabstr = entry['IsAbstract'];
					}
					var pnid = "#";
					let pnode = await getParentRef(entry, m);
					command = "INSERT INTO ns"+m+"objecttypes(nodeid, nodeidtype, nsindex, nsurl, name, displayname, browsename, parentid, parentreference, parentinverse, isabstract, description, documentation) VALUES ('"+entry['NodeId']+"', '"+nid_t+"', '"+idx+"', '"+url+"', '"+entry['DisplayName']+"', '"+entry['DisplayName']+"', '"+entry['BrowseName']+"', '"+pnode.pnid+"', '"+pnode.pref+"', '"+pnode.pinv+"', '"+isabstr+"', '"+entry['Description']+"', '"+entry['Documentation']+"');";
					ret = pool.query(command);
				}
				
			}else{
				var entry = obj;
				var nid = entry['NodeId'];
				var idx = 0;
				if(nid.includes('ns=')){
					var ix = nid.indexOf(';');
					var ns = nid.substring(3,ix);
					idx = parseInt(ns);
				}
				await checkRefs(entry, m, url);
				var nid_t = "";
				if(nid.includes('i=')){
					nid_t = 'Numeric';
				}else if(nid.includes('s=')){
					nid_t = 'String';
				}
				var isabstr = "TBD";
				if(entry['IsAbstract']){
					isabstr = entry['IsAbstract'];
				}
				let pnode = await getParentRef(entry, m);
				command = "INSERT INTO ns"+m+"objecttypes(nodeid, nodeidtype, nsindex, nsurl, name, displayname, browsename, parentid, parentreference, parentinverse, isabstract, description, documentation) VALUES ('"+entry['NodeId']+"', '"+nid_t+"', '"+idx+"', '"+url+"', '"+entry['DisplayName']+"', '"+entry['DisplayName']+"', '"+entry['BrowseName']+"', '"+pnode.pnid+"', '"+pnode.pref+"', '"+pnode.pinv+"', '"+isabstr+"', '"+entry['Description']+"', '"+entry['Documentation']+"');";
				ret = pool.query(command);
			}
		}
	
	}catch(err){
		console.log(err);
	}
}

async function createVar(m){
	try{
		var command = "CREATE TABLE IF NOT EXISTS ns"+m+"variables(id INT AUTO_INCREMENT, nodeid VARCHAR(300) NOT NULL UNIQUE, nodeidtype VARCHAR(100) NOT NULL, name VARCHAR(300) NOT NULL, nodeclass VARCHAR(50) DEFAULT 'Variable', nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', displayname VARCHAR(300) NOT NULL, browsename VARCHAR(300) NOT NULL, description VARCHAR(300), modellingrule VARCHAR(100) DEFAULT 'Optional', datatype VARCHAR(300) NOT NULL, typedefinition VARCHAR(300) NOT NULL, value VARCHAR(500) DEFAULT NULL, valuerank INT DEFAULT NULL, arraydimensions INT, accesslevel INT DEFAULT NULL, accesslevelex INT DEFAULT NULL, historizing VARCHAR(10), minsamplinginterval INT DEFAULT 500, releasestatus VARCHAR(300), parentid VARCHAR(300) DEFAULT '#', parentreference VARCHAR(300), parentinverse VARCHAR(10), documentation VARCHAR(300), comment VARCHAR(300), PRIMARY KEY(id));";
		var ret = await pool.query(command);
		let obj = nsray[m].UANodeSet.UAVariable;
		var url = nsray[m].UANodeSet.Models.Model.ModelUri;
		if(nsray[m].UANodeSet.UAVariable){
			if(Array.isArray(obj)){
				var sz = obj.length;
				for(let i = 0; i < sz; i++){
					var entry = obj[i];
					var nid = entry['NodeId'];
					var idx = 0;
					if(nid.includes('ns=')){
						var ix = nid.indexOf(';');
						var ns = nid.substring(3,ix);
						idx = parseInt(ns);
					}
					await checkRefs(entry, m, url);
					var nid_t = "";
					if(nid.includes('i=')){
						nid_t = 'Numeric';
					}else if(nid.includes('s=')){
						nid_t = 'String';
					}
					var valrank = 0;
					if(entry['ValueRank']){
						valrank = entry['ValueRank'];
					}
					var arrdim = 0;
					if(entry['ArrayDimensions']){
						arrdim = entry['ArrayDimensions'];
					}
					var acclev = 0;
					if(entry['AccessLevel']){
						acclev = entry['AccessLevel'];
					}
					var minsamp = 0;
					if(entry['MinimumSamplingInterval']){
						minsamp = entry['MinimumSamplingInterval'];
					}
					var dt = entry['DataType'];
					if(entry['DataType'] && dt.includes('=')){
						dt = await getDataType(dt, m);
					}
					var tt = await getTypeDef(entry['NodeId'], m);
					let pnode = await getParentRef(entry, m);
					command = "INSERT INTO ns"+m+"variables(nodeid, nodeidtype, nsindex, nsurl, name, displayname, browsename, parentid, parentreference, parentinverse, typedefinition, description, datatype, valuerank, arraydimensions, accesslevel, minsamplinginterval, releasestatus) VALUES ('"+entry['NodeId']+"', '"+nid_t+"', '"+idx+"', '"+url+"', '"+entry['DisplayName']+"', '"+entry['DisplayName']+"', '"+entry['BrowseName']+"', '"+pnode.pnid+"', '"+pnode.pref+"', '"+pnode.pinv+"', '"+tt+"', '"+entry['Description']+"', '"+dt+"', '"+valrank+"', '"+arrdim+"', '"+acclev+"', '"+minsamp+"', '"+entry['ReleaseStatus']+"');";
					ret = await pool.query(command);
				}
				
			}else{
				var entry = obj;
				var nid = entry['NodeId'];
				var idx = 0;
				if(nid.includes('ns=')){
					var ix = nid.indexOf(';');
					var ns = nid.substring(3,ix);
					idx = parseInt(ns);
				}
				await checkRefs(entry, m, url);
				var nid_t = "";
				if(nid.includes('i=')){
					nid_t = 'Numeric';
				}else if(nid.includes('s=')){
					nid_t = 'String';
				}
				var valrank = 0;
				if(entry['ValueRank']){
					valrank = entry['ValueRank'];
				}
				var arrdim = 0;
				if(entry['ArrayDimensions']){
					arrdim = entry['ArrayDimensions'];
				}
				var acclev = 0;
				if(entry['AccessLevel']){
					acclev = entry['AccessLevel'];
				}
				var minsamp = 0;
				if(entry['MinimumSamplingInterval']){
					minsamp = entry['MinimumSamplingInterval'];
				}
				var dt = entry['DataType'];
				if(entry['DataType'] && dt.includes('=')){
					dt = await getDataType(nid, m);
				}
				var tt = await getTypeDef(entry['NodeId'], m);
				let pnode = await getParentRef(entry, m);
				command = "INSERT INTO ns"+m+"variables(nodeid, nodeidtype, nsindex, nsurl, name, displayname, browsename, parentid, parentreference, parentinverse, typedefinition, parentid, description, datatype, valuerank, arraydimensions, accesslevel, minsamplinginterval, releasestatus) VALUES ('"+entry['NodeId']+"', '"+nid_t+"', '"+idx+"', '"+url+"', '"+entry['DisplayName']+"', '"+entry['DisplayName']+"', '"+entry['BrowseName']+"', '"+pnode.pnid+"', '"+pnode.pref+"', '"+pnode.pinv+"', '"+tt+"','#', '"+entry['Description']+"', '"+dt+"', '"+valrank+"', '"+arrdim+"', '"+acclev+"', '"+minsamp+"', '"+entry['ReleaseStatus']+"');";
				ret = await pool.query(command);
			}
		}
	}catch(err){
		console.log(err);
	}
}

async function createVarTypes(m){
	try{
		var command = "CREATE TABLE IF NOT EXISTS ns"+m+"variabletypes(id INT AUTO_INCREMENT, nodeid VARCHAR(300) NOT NULL UNIQUE, nodeidtype VARCHAR(100) NOT NULL, name VARCHAR(300) NOT NULL, nodeclass VARCHAR(50) DEFAULT 'VariableType', nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', displayname VARCHAR(300) NOT NULL, browsename VARCHAR(300) NOT NULL, description VARCHAR(300), datatype VARCHAR(300) NOT NULL, value VARCHAR(500) DEFAULT NULL, valuerank INT DEFAULT NULL, arraydimensions INT, isabstract VARCHAR(10), parentid VARCHAR(300) DEFAULT '#', parentreference VARCHAR(300), parentinverse VARCHAR(10), documentation VARCHAR(300), comment VARCHAR(300), PRIMARY KEY(id));";
		var ret = await pool.query(command);
		let obj = nsray[m].UANodeSet.UAVariableType;
		var url = nsray[m].UANodeSet.Models.Model.ModelUri;
		if(nsray[m].UANodeSet.UAVariableType){
			if(Array.isArray(obj)){
				var sz = obj.length;
				for(let i = 0; i < sz; i++){
					console.log(obj[i]);
					var entry = obj[i];
					var nid = entry['NodeId'];
					var idx = 0;
					if(nid.includes('ns=')){
						var ix = nid.indexOf(';');
						var ns = nid.substring(3,ix);
						idx = parseInt(ns);
					}
					await checkRefs(entry, m, url);
					var nid_t = "";
					if(nid.includes('i=')){
						nid_t = 'Numeric';
					}else if(nid.includes('s=')){
						nid_t = 'String';
					}
					var valrank = 0;
					if(entry['ValueRank']){
						valrank = entry['ValueRank'];
					}
					var arrdim = 0;
					if(entry['ArrayDimensions']){
						console.log('Here');
						console.log(entry['ArrayDimensions']);
						arrdim = entry['ArrayDimensions'];
					}
					var isabstr = "TBD";
					if(entry['IsAbstract']){
						isabstr = entry['IsAbstract'];
					}
					var dt = entry['DataType'];
					if(entry['DataType'] && dt.includes('=')){
						dt = await getDataType(nid, m);
					}
					let pnode = await getParentRef(entry, m);					
					command = "INSERT INTO ns"+m+"variabletypes(nodeid, nodeidtype, nsindex, nsurl, name, displayname, browsename, parentid, parentreference, parentinverse, description, datatype, valuerank, arraydimensions, isabstract, documentation) VALUES ('"+entry['NodeId']+"', '"+nid_t+"', '"+idx+"', '"+url+"', '"+entry['DisplayName']+"', '"+entry['DisplayName']+"', '"+entry['BrowseName']+"','"+pnode.pnid+"', '"+pnode.pref+"', '"+pnode.pinv+"', '"+entry['Description']+"', '"+dt+"', '"+valrank+"', '"+arrdim+"', '"+isabstr+"', '"+entry['Documentation']+"');";
					ret = pool.query(command);
				}
			}else{
				var entry = obj;
				var nid = entry['NodeId'];
				var idx = 0;
				if(nid.includes('ns=')){
					var ix = nid.indexOf(';');
					var ns = nid.substring(3,ix);
					idx = parseInt(ns);
				}
				await checkRefs(entry, m, url);
				var nid_t = "";
				if(nid.includes('i=')){
					nid_t = 'Numeric';
				}else if(nid.includes('s=')){
					nid_t = 'String';
				}
				var valrank = 0;
				if(entry['ValueRank']){
					valrank = entry['ValueRank'];
				}
				var arrdim = 0;
				if(entry['ArrayDimensions']){
					console.log('Here');
					console.log(entry['ArrayDimensions']);
					arrdim = entry['ArrayDimensions'];
				}
				var isabstr = "TBD";
				if(entry['IsAbstract']){
					isabstr = entry['IsAbstract'];
				}
				var dt = entry['DataType'];
				if(entry['DataType'] && dt.includes('=')){
					dt = await getDataType(nid, m);
				}
				let pnode = await getParentRef(entry, m);
				command = "INSERT INTO ns"+m+"variabletypes(nodeid, nodeidtype, nsindex, nsurl, name, displayname, browsename, parentid, parentreference, parentinverse, description, datatype, valuerank, arraydimensions, isabstract, documentation) VALUES ('"+entry['NodeId']+"', '"+nid_t+"', '"+idx+"', '"+url+"', '"+entry['DisplayName']+"', '"+entry['DisplayName']+"', '"+entry['BrowseName']+"','"+pnode.pnid+"', '"+pnode.pref+"', '"+pnode.pinv+"', '"+entry['Description']+"', '"+dt+"', '"+valrank+"', '"+arrdim+"', '"+isabstr+"', '"+entry['Documentation']+"');";
				ret = pool.query(command);	
	
			}
		}
	}catch(err){
		console.log(err);
	}
}

async function createMethods(m){
	try{
		var command = "CREATE TABLE IF NOT EXISTS ns"+m+"methods(id INT AUTO_INCREMENT, nodeid VARCHAR(300) NOT NULL UNIQUE, nodeidtype VARCHAR(100) NOT NULL, name VARCHAR(300) NOT NULL, nodeclass VARCHAR(50) DEFAULT 'Method', nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', displayname VARCHAR(300) NOT NULL, browsename VARCHAR(300) NOT NULL, description VARCHAR(300), modellingrule VARCHAR(100) DEFAULT 'Optional', executable INT DEFAULT 1, parentreference VARCHAR(300), parentid VARCHAR(300) DEFAULT '#', methoddeclarationid VARCHAR(300), parentinverse VARCHAR(10), documentation VARCHAR(300), comment VARCHAR(300), PRIMARY KEY(id));";		
		var ret = await pool.query(command);
		let obj = nsray[m].UANodeSet.UAMethod;
		var url = nsray[m].UANodeSet.Models.Model.ModelUri;
		if(nsray[m].UANodeSet.UAMethod){
			if(Array.isArray(obj)){
				var sz = obj.length;
				for(let i = 0; i < sz; i++){
					var entry = obj[i];
					var nid = entry['NodeId'];
					var idx = 0;
					if(nid.includes('ns=')){
						var ix = nid.indexOf(';');
						var ns = nid.substring(3,ix);
						idx = parseInt(ns);
					}
					await checkRefs(entry, m, url);
					var nid_t = "";
					if(nid.includes('i=')){
						nid_t = 'Numeric';
					}else if(nid.includes('s=')){
						nid_t = 'String';
					}
					let pnode = await getParentRef(entry, m);
					command = "INSERT INTO ns"+m+"methods(nodeid, nodeidtype, nsindex, nsurl, name, displayname, browsename, parentid, parentreference, parentinverse, description, methoddeclarationid) VALUES ('"+entry['NodeId']+"', '"+nid_t+"', '"+idx+"', '"+url+"', '"+entry['DisplayName']+"', '"+entry['DisplayName']+"', '"+entry['BrowseName']+"', '"+pnode.pnid+"', '"+pnode.pref+"', '"+pnode.pinv+"', '"+entry['Description']+"', '"+entry['MethodDeclarationId']+"');";
					ret = pool.query(command);
				}
			}else{
				var entry = obj;
				var nid = entry['NodeId'];
				var idx = 0;
				if(nid.includes('ns=')){
					var ix = nid.indexOf(';');
					var ns = nid.substring(3,ix);
					idx = parseInt(ns);
				}
				await checkRefs(entry, m, url);
				var nid_t = "";
				if(nid.includes('i=')){
					nid_t = 'Numeric';
				}else if(nid.includes('s=')){
					nid_t = 'String';
				}
				let pnode = await getParentRef(entry, m);
				command = "INSERT INTO ns"+m+"methods(nodeid, nodeidtype, nsindex, nsurl, name, displayname, browsename, parentid, parentreference, parentinverse, description, methoddeclarationid) VALUES ('"+entry['NodeId']+"', '"+nid_t+"', '"+idx+"', '"+url+"', '"+entry['DisplayName']+"', '"+entry['DisplayName']+"', '"+entry['BrowseName']+"', '"+pnode.pnid+"', '"+pnode.pref+"', '"+pnode.pinv+"', '"+entry['Description']+"', '"+entry['MethodDeclarationId']+"');";
				
				ret = pool.query(command);
			}
		}
	
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}
}

async function createDataTypes(m){
	try{
		var command = "CREATE TABLE IF NOT EXISTS ns"+m+"datatypes(id INT AUTO_INCREMENT, nodeid VARCHAR(300) NOT NULL UNIQUE, nodeidtype VARCHAR(100) NOT NULL, name VARCHAR(300) NOT NULL, nodeclass VARCHAR(50) DEFAULT 'DataType', nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', displayname VARCHAR(300) NOT NULL, browsename VARCHAR(300) NOT NULL, description VARCHAR(300), isabstract VARCHAR(10), parentid VARCHAR(300) DEFAULT '#', parentreference VARCHAR(300), parentinverse VARCHAR(10), definition VARCHAR(300), releasestatus VARCHAR(300), documentation VARCHAR(300), comment VARCHAR(300), PRIMARY KEY(id));";
		var ret = await pool.query(command);
		let obj = nsray[m].UANodeSet.UADataType;
		var url = nsray[m].UANodeSet.Models.Model.ModelUri;
		if(nsray[m].UANodeSet.UADataType){
			if(Array.isArray(obj)){
				var sz = obj.length;
				for(let i = 0; i < sz; i++){
					var entry = obj[i];
					var nid = entry['NodeId'];
					var idx = 0;
					if(nid.includes('ns=')){
						var ix = nid.indexOf(';');
						var ns = nid.substring(3,ix);
						idx = parseInt(ns);
					}
					await checkRefs(entry, m, url);
					var nid_t = "";
					if(nid.includes('i=')){
						nid_t = 'Numeric';
					}else if(nid.includes('s=')){
						nid_t = 'String';
					}
					let pnode = await getParentRef(entry, m);
					command = "INSERT INTO ns"+m+"datatypes(nodeid, nodeidtype, nsindex, nsurl, name, displayname, browsename, parentid, parentreference, parentinverse, description, isabstract, definition, releasestatus, documentation) VALUES ('"+entry['NodeId']+"', '"+nid_t+"', '"+idx+"', '"+url+"', '"+entry['DisplayName']+"', '"+entry['DisplayName']+"', '"+entry['BrowseName']+"', '"+pnode.pnid+"', '"+pnode.pref+"', '"+pnode.pinv+"', '"+entry['Description']+"', '"+entry['IsAbstract']+"', '"+entry['Definition']+"', '"+entry['ReleaseStatus']+"', '"+entry['Documentation']+"');";
					ret = pool.query(command);
				}
			}else{
				var entry = obj;
				var nid = entry['NodeId'];
				var idx = 0;
				if(nid.includes('ns=')){
					var ix = nid.indexOf(';');
					var ns = nid.substring(3,ix);
					idx = parseInt(ns);
				}
				await checkRefs(entry, m, url);
				var nid_t = "";
				if(nid.includes('i=')){
					nid_t = 'Numeric';
				}else if(nid.includes('s=')){
					nid_t = 'String';
				}
				let pnode = await getParentRef(entry, m);
				command = "INSERT INTO ns"+m+"datatypes(nodeid, nodeidtype, nsindex, name, displayname, browsename, parentid, parentreference, parentinverse, description, isabstract, definition, releasestatus, documentation) VALUES ('"+entry['NodeId']+"', '"+nid_t+"', '"+idx+"', '"+url+"', '"+entry['DisplayName']+"', '"+entry['DisplayName']+"', '"+entry['BrowseName']+"', '"+pnode.pnid+"', '"+pnode.pref+"', '"+pnode.pinv+"', '"+entry['Description']+"', '"+entry['IsAbstract']+"', '"+entry['Definition']+"', '"+entry['ReleaseStatus']+"', '"+entry['Documentation']+"');";
				ret = pool.query(command);
			}
		}
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
	}
}

async function createRefTypes(m){
	try{
		var command = "CREATE TABLE IF NOT EXISTS ns"+m+"referencetypes(id INT AUTO_INCREMENT, nodeid VARCHAR(300) NOT NULL UNIQUE, nodeidtype VARCHAR(100) NOT NULL, name VARCHAR(300) NOT NULL, inversename VARCHAR(300), symmetric VARCHAR(10) DEFAULT 'TBD', nodeclass VARCHAR(50) DEFAULT 'ReferenceType', nsindex INT DEFAULT NULL, nsurl VARCHAR(120) DEFAULT 'http://opcfoundation.org/UA/', displayname VARCHAR(300) NOT NULL, browsename VARCHAR(300) NOT NULL, description VARCHAR(300), isabstract VARCHAR(10) DEFAULT 'TBD', parentid VARCHAR(300) DEFAULT '#', parentreference VARCHAR(300), parentinverse VARCHAR(10), documentation VARCHAR(300), comment VARCHAR(300), PRIMARY KEY(id));";
		var ret = await pool.query(command);
		let obj = nsray[m].UANodeSet.UAReferenceType;
		var url = nsray[m].UANodeSet.Models.Model.ModelUri;
		if(nsray[m].UANodeSet.UAReferenceType){
			if(Array.isArray(obj)){
				var sz = obj.length;
				for(let i = 0; i < sz; i++){
					var entry = obj[i];
					var nid = entry['NodeId'];
					var idx = m;
					if(nid.includes('ns=')){
						var ix = nid.indexOf(';');
						var ns = nid.substring(3,ix);
						idx = parseInt(ns);
					}
					await checkRefs(entry, m, url);
					var nid_t = "";
					if(nid.includes('i=')){
						nid_t = 'Numeric';
					}else if(nid.includes('s=')){
						nid_t = 'String';
					}
					let pnode = await getParentRef(entry, m);
					command = "INSERT INTO ns"+m+"referencetypes(nodeid, nodeidtype, nsindex, nsurl, name, displayname, browsename, parentid, parentreference, parentinverse, description, isabstract, symmetric, inversename, documentation) VALUES ('"+entry['NodeId']+"', '"+nid_t+"', '"+idx+"', '"+url+"', '"+entry['DisplayName']+"', '"+entry['DisplayName']+"', '"+entry['BrowseName']+"', '"+pnode.pnid+"', '"+pnode.pref+"', '"+pnode.pinv+"', '"+entry['Description']+"', '"+entry['IsAbstract']+"', '"+entry['Symmetric']+"', '"+entry['InverseName']+"', '"+entry['Documentation']+"');";
					ret = pool.query(command);
				}
			}else{
				var entry = obj;
				var nid = entry['NodeId'];
				var idx = m;
				if(nid.includes('ns=')){
					var ix = nid.indexOf(';');
					var ns = nid.substring(3,ix);
					idx = parseInt(ns);
				}
				await checkRefs(entry, m, url);
				var nid_t = "";
				if(nid.includes('i=')){
					nid_t = 'Numeric';
				}else if(nid.includes('s=')){
					nid_t = 'String';
				}
				let pnode = await getParentRef(entry, m);
				command = "INSERT INTO ns"+m+"referencetypes(nodeid, nodeidtype, nsindex, nsurl, name, displayname, browsename, parentid, parentreference, parentinverse, parentreference, parentinverse, description, isabstract, symmetric, inversename, documentation) VALUES ('"+entry['NodeId']+"', '"+nid_t+"', '"+idx+"', '"+url+"', '"+entry['DisplayName']+"', '"+entry['DisplayName']+"', '"+entry['BrowseName']+"', '"+pnode.pnid+"', '"+pnode.pref+"', '"+pnode.pinv+"', '"+entry['Description']+"', '"+entry['IsAbstract']+"', '"+entry['Symmetric']+"', '"+entry['InverseName']+"', '"+entry['Documentation']+"');";
				ret = pool.query(command);
			}
		}
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
	}
}

app.get('/obj', async function(req, res){
	try{
		var key = req.body;	
		var len = nsray.length;
		for(let m = 0; m < nsray.length; m++){
			await createObj(m);
		}
		
		res.json({result:'OK',success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}

})

app.get('/obj/:id', async function(req, res){
	try{
		var key = req.body;
		var m = parseInt(req.params["id"]);		
		await createObj(m);		
		res.json({result:'OK',success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}
})

app.get('/objtypes', async function(req, res){
	try{
		var key = req.body;	
		var len = nsray.length;
		for(let m = 0; m < nsray.length; m++){
			await createObjTypes(m);
		}
		res.json({result:'OK',success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}

})

app.get('/objtypes/:id', async function(req, res){
	try{
		var m = parseInt(req.params["id"]);	
		await createObjTypes(m);
		res.json({result:'OK',success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}
})

app.get('/var', async function(req, res){
	try{
		var key = req.body;	
		var len = nsray.length;
		for(let m = 0; m < nsray.length; m++){
			await createVar(m);
		}
		res.json({result:'OK',success:true});	
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}
})

app.get('/var/:id', async function(req, res){
	try{
		var m = parseInt(req.params["id"]);
		await createVar(m);
		res.json({result:'OK',success:true});	
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
	}
})

app.get('/vartypes', async function(req, res){
	try{
		var key = req.body;	
		var len = nsray.length;
		for(let m = 0; m < nsray.length; m++){
			await createVarTypes(m);
		}
		res.json({result:'OK',success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}
})

app.get('/vartypes/:id', async function(req, res){
	try{
		var m = parseInt(req.params["id"]);
		await createVarTypes(m);
		res.json({result:'OK',success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}
})

app.get('/methods', async function(req, res){
	try{
		var key = req.body;	
		var len = nsray.length;
		for(let m = 0; m < nsray.length; m++){
			await createMethods(m);
		}
		res.json({result:'OK',success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}

})

app.get('/methods/:id', async function(req, res){
	try{
		var m = parseInt(req.params["id"]);
		await createMethods(m);
		
		res.json({result:'OK',success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}
})

app.get('/datatypes', async function(req, res){
	try{
		var key = req.body;
		var len = nsray.length;
		for(let m = 0; m < nsray.length; m++){
			await createDataTypes(m);
		}
		res.json({result:'OK',success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}

})

app.get('/datatypes/:id', async function(req, res){
	try{
		var m = parseInt(req.params["id"]);
		await createDataTypes(m);
		
		res.json({result:'OK',success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}

})

app.get('/reftypes', async function(req, res){
	try{
		var key = req.body;	
		var len = nsray.length;
		for(let m = 0; m < nsray.length; m++){
			await createRefTypes(m);
		}
		res.json({result:'OK',success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}

})

app.get('/reftypes/:id', async function(req, res){
	try{
		var m = parseInt(req.params["id"]);
		await createRefTypes(m);
		res.json({result:'OK',success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}

})

app.get('/createnodes/:id', async function(req, res){
	try{
		var m = parseInt(req.params["id"]);
		await createDataTypes(m);
		await createObjTypes(m);
		await createVarTypes(m);
		await createRefTypes(m);
		await createObj(m);
		await createVar(m);
		await createMethods(m);
		
		res.json({result:'OK',success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
		}

})



app.get('/namesp', async function(req, res){
	try{
		var key = req.body;	
		var sz = nsray.length;
		//-------ns0--------------
		var command = "CREATE TABLE IF NOT EXISTS ns0depends(id INT AUTO_INCREMENT, nsindex INT DEFAULT NULL, nsurl VARCHAR(120), publicationdate VARCHAR(120), version VARCHAR(100), PRIMARY KEY(id));";
		var ret = await pool.query(command);
		command = "INSERT INTO ns0depends(nsindex, nsurl, publicationdate, version) VALUES ('0','http://opcfoundation.org/UA/','"+jsn.UANodeSet.Models.Model['PublicationDate']+"','"+jsn.UANodeSet.Models.Model['Version']+"');";
		ret = pool.query(command);
		//----------------ns0--------------
		for(let i = 1; i < sz; i++){
			var entry0 = nsray[i].UANodeSet.NamespaceUris.Uri;
			command = "CREATE TABLE IF NOT EXISTS ns"+i+"depends(id INT AUTO_INCREMENT, nsindex INT DEFAULT NULL, nsurl VARCHAR(120), publicationdate VARCHAR(120), version VARCHAR(100), PRIMARY KEY(id));";
			ret = await pool.query(command);
			command = "INSERT INTO ns"+i+"depends(nsindex, nsurl, publicationdate, version) VALUES ('0','http://opcfoundation.org/UA/','"+jsn.UANodeSet.Models.Model['PublicationDate']+"','"+jsn.UANodeSet.Models.Model['Version']+"');";
			ret = pool.query(command);
			if(Array.isArray(entry0)){
				var szy = entry0.length;
				for(let y = 0; y < szy; y++){
					var ns = entry0[y];
					command = "INSERT INTO ns"+i+"depends(nsindex, nsurl) VALUES ('"+(y+1)+"','"+ns+"');";
					ret = pool.query(command);
				}
			}else{
				var ns = entry0;
				command = "INSERT INTO ns"+i+"depends(nsindex, nsurl) VALUES ('1','"+entry0+"');";
				ret = pool.query(command);
			}
			var entry = nsray[i].UANodeSet.Models.Model.RequiredModel;
			command = "UPDATE ns"+i+"depends SET publicationdate = '"+nsray[i].UANodeSet.Models.Model['PublicationDate']+"' WHERE nsurl = '"+nsray[i].UANodeSet.Models.Model['ModelUri']+"';";
			ret = pool.query(command);
			command = "UPDATE ns"+i+"depends SET version = '"+nsray[i].UANodeSet.Models.Model['Version']+"' WHERE nsurl = '"+nsray[i].UANodeSet.Models.Model['ModelUri']+"';";
			ret = pool.query(command);
			
			if(Array.isArray(entry)){
				var szy = entry.length;
				for(let y = 0; y < szy; y++){
					var ns0 = entry[y];
					command = "UPDATE ns"+i+"depends SET publicationdate = '"+ns0['PublicationDate']+"' WHERE nsurl = '"+ns0['ModelUri']+"';";
					ret = pool.query(command);
					command = "UPDATE ns"+i+"depends SET version = '"+ns0['Version']+"' WHERE nsurl = '"+ns0['ModelUri']+"';";
					ret = pool.query(command);
				}
			}else{
				var ns0 = entry;
				command = "UPDATE ns"+i+"depends SET publicationdate = '"+ns0['PublicationDate']+"' WHERE nsurl = '"+ns0['ModelUri']+"';";
				ret = pool.query(command);
				command = "UPDATE ns"+i+"depends SET version = '"+ns0['Version']+"' WHERE nsurl = '"+ns0['ModelUri']+"';";
				ret = pool.query(command);
			}			
		}
		res.json({result:'OK',success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
	}
})



app.get('/allrefs', async function(req, res){
	try{
		console.log(arref);
		res.json({result:'OK',success:true});
	}catch(err){
		console.log("NOK");
		res.json({result:"NOK"});
		}

})


app.get('/init', async function(req, res){
	try{
		var len = nsray.length;
		for(let m = 0; m < nsray.length; m++){
			await createNamespace(m);
		}
		res.json({result:'OK',success:true});
	}catch(err){
		console.log("NOK");
		res.json({result:"NOK"});
		}

})

app.get('/init/:ns', async function(req, res){
	try{
		var n = req.params["ns"];
		await createNamespace(n);
		res.json({result:'OK',success:true});
	}catch(err){
		console.log("NOK");
		res.json({result:"NOK"});
		}

})


/*
app.post('/key', async function(req, res){
	try{
		var key = req.body;	
		console.log(key);
		var ret = await gen_query("SELECT name FROM mitarbeiter WHERE key_id='"+key['key_id']+"';");
		res.json({result:ret[0].name,success:true});
	}catch(err){
		console.log("NOK");
		res.json({result:"NOK"});
		}

})
*/

app.get('/look/:ix/:id/:eclass/:attr', async function(req, res){
	try{
		var ix = req.params["ix"];
		var id = req.params["id"];
		var cls = req.params["eclass"];
		var attr = req.params["attr"];
		var class_name = "";
		switch(cls){
			case "ObjectType": class_name="objecttypes"; break; 
			case "Object": class_name="objects"; break;
			case "VariableType": class_name="variabletypes"; break;
			case "DataType": class_name="datatypes"; break;
			case "ReferenceType": class_name="referencetypes"; break;
			case "Variable": class_name="variables"; break;
			case "Method": class_name="methods"; break;
			default: class_name="objects";
		}
		var ret = await getThisNodeAttribute(ix, id, class_name, attr);
		res.json({result:ret,success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
	}

})

app.get('/find/:ix/:id/:eclass', async function(req, res){
	try{
		var ix = req.params["ix"];
		var id = req.params["id"];
		var cls = req.params["eclass"];
		var class_name = "";
		switch(cls){
			case "ObjectType": class_name="objecttypes"; break; 
			case "Object": class_name="objects"; break;
			case "VariableType": class_name="variabletypes"; break;
			case "DataType": class_name="datatypes"; break;
			case "ReferenceType": class_name="referencetypes"; break;
			case "Variable": class_name="variables"; break;
			case "Method": class_name="methods"; break;
			default: class_name="objects";
		}
		var ret = await getThisNode(ix, id, class_name);
		res.json(ret);
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
	}

})

app.get('/children/sql/:ix/:id', async function(req, res){
	try{
		var ix = req.params["ix"];
		var id = req.params["id"];
		var ret = await getChildrenSql(ix, id);
		res.json({result:ret, success: true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
	}

})


app.get('/typedef', async function(req, res){
	try{
		var ret = await getTypeDef("ns=1;i=103", 4);
		res.json({result:ret,success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
	}

})

app.get('/parent', async function(req, res){
	try{
		var ret = await getParentRef("ns=1;i=118", 4);
		res.json({result:ret,success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
	}

})

app.get('/delete', async function(req, res){
	try{
		for(let i = 1; i < 5; i++){
			var command = "DROP TABLE ns"+i+"objects;";
			var ret = await pool.query(command);
			var command = "DROP TABLE ns"+i+"objecttypes;";
			var ret = await pool.query(command);
			var command = "DROP TABLE ns"+i+"variables;";
			var ret = await pool.query(command);
			var command = "DROP TABLE ns"+i+"variabletypes;";
			var ret = await pool.query(command);
			var command = "DROP TABLE ns"+i+"datatypes;";
			var ret = await pool.query(command);
			var command = "DROP TABLE ns"+i+"referencetypes;";
			var ret = await pool.query(command);
			var command = "DROP TABLE ns"+i+"references;";
			var ret = await pool.query(command);
			var command = "DROP TABLE ns"+i+"methods;";
			var ret = await pool.query(command);
		}
		res.json({result:"OK",success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
	}

})

app.get('/delete/:id', async function(req, res){
	try{
		var i = req.params["id"];
		
			var command = "DROP TABLE ns"+i+"objects;";
			var ret = await pool.query(command);
			var command = "DROP TABLE ns"+i+"objecttypes;";
			var ret = await pool.query(command);
			var command = "DROP TABLE ns"+i+"variables;";
			var ret = await pool.query(command);
			var command = "DROP TABLE ns"+i+"variabletypes;";
			var ret = await pool.query(command);
			var command = "DROP TABLE ns"+i+"datatypes;";
			var ret = await pool.query(command);
			var command = "DROP TABLE ns"+i+"referencetypes;";
			var ret = await pool.query(command);
			var command = "DROP TABLE ns"+i+"references;";
			var ret = await pool.query(command);
			var command = "DROP TABLE ns"+i+"methods;";
			var ret = await pool.query(command);
		
		res.json({result:"OK",success:true});
	}catch(err){
		console.log(err);
		res.json({result:"NOK"});
	}

})


app.get('/requirejson/:ident/:name',(req, res) =>{
	try{
		var namejs = req.params["name"];
		var shorty = req.params["ident"];
		const id = "./"+namejs+".json";
		const fl = require(id);
		for(let i = 0; i < ns_array.length; i++){
			if(ns_array[i][1] === shorty){
				return res.json({result:"Array already includes element."}) 
				}
			}

		ns_array.push([fl, shorty, fl.UANodeSet.Models.Model.ModelUri]);	
		res.json({result:"OK"});
		
	}catch(err){
		console.log("NOK");
		res.json({result:"NOK", error: "Json file may not be available. Call list json files."});
		}

})

app.get('/shownsarray',(req, res) =>{
	try{ let str = '';
		for(let i = 0; i < ns_array.length; i++){
			str += '('+i+': '+ns_array[i][1]+')';
			}
		res.json({result:str});
		console.log(ns_array);
	}catch(err){
		console.log("NOK");
		res.json({result:"NOK", error: "Json file may not be available. Call list json files."});
		}

})

app.get('/getredis',(req, res) =>{
	try{
		redis_get();
		res.json({result:"OK"});
	}catch(err){
		console.log("NOK");
		res.json({result:"NOK"});
	}

})

app.get('/get_root',(req, res) =>{
	try{
		let rt = jsn.UANodeSet.UAObject.find( record => record.NodeId === "i=84");
		let resj = {
			id: rt.NodeId,
			parent: "#",
			text: rt.DisplayName};
		res.json(resj);
	}catch(err){
		console.log("NOK");
		res.json({result:"NOK"});
	}

})

app.get('/get_children/base/:id',(req, res) =>{
	var nid = req.params["id"];
	try{
		if(Array.isArray(jsn.UANodeSet.UAObject)){
			for (let i = 0; i < jsn.UANodeSet.UAObject.length;i++){
				if(Array.isArray(jsn.UANodeSet.UAObject[i].References.Reference)){
					for (let x = 0; x < jsn.UANodeSet.UAObject[i].References.Reference.length;x++){
						if(jsn.UANodeSet.UAObject[i].References.Reference[x].$t === nid){
							console.log(jsn.UANodeSet.UAObject[i].BrowseName + inverse(jsn.UANodeSet.UAObject[i].References.Reference[x]) +jsn.UANodeSet.UAObject[i].References.Reference[x].ReferenceType);
							}
						}
					}else{
						if(jsn.UANodeSet.UAObject[i].References.Reference.$t === nid){
							console.log(jsn.UANodeSet.UAObject[i].BrowseName + inverse(jsn.UANodeSet.UAObject[i].References.Reference) +jsn.UANodeSet.UAObject[i].References.Reference.ReferenceType);
						}
					}
			}
		}else{
			if(Array.isArray(jsn.UANodeSet.UAObject.References.Reference)){
				for (let x = 0; x < jsn.UANodeSet.UAObject.References.Reference.length;x++){
					if(jsn.UANodeSet.UAObject[i].References.Reference[x].$t === nid){
						console.log(jsn.UANodeSet.UAObject[i].BrowseName + inverse(jsn.UANodeSet.UAObject.References.Reference[x]) +jsn.UANodeSet.UAObject.References.Reference[x].ReferenceType);
					}
				}
			}else{
				if(jsn.UANodeSet.UAObject.References.Reference.$t === nid){
					console.log(jsn.UANodeSet.UAObject.BrowseName + inverse(jsn.UANodeSet.UAObject.References.Reference) +jsn.UANodeSet.UAObject.References.Reference.ReferenceType);
				}
			}		
		}
		console.log('');
		res.json({result:"OK"});
	}catch(err){
		console.log("NOK");
		res.json({result:"NOK"});
	}
})

app.get('/get_children/all/:ns/:id',(req, res) =>{
	var ret_obj = [];
	var ns = req.params["ns"];
	var id = req.params["id"];
	var nid = 'ns='+ns+';'+'i='+id;
	console.log(nid);
	get_Children(di, nid, ret_obj);
	get_Children(ia, nid, ret_obj);
	get_Children(mach, nid, ret_obj);
	get_Children(mt, nid, ret_obj);
	
	res.json(ret_obj);
})

app.get('/getNode/all/:ns/:id',(req, res) =>{
	var ret_obj = [];
	var ns = req.params["ns"];
	var id = req.params["id"];
	var nid = 'ns='+ns+';'+'i='+id;
	console.log(nid);
	get_Children(di, nid, ret_obj);
	get_Children(ia, nid, ret_obj);
	get_Children(mach, nid, ret_obj);
	get_Children(mt, nid, ret_obj);
	let node = {
		id:nid,
		text: "home",
		children:ret_obj
	}
	res.json(node);
})


app.get('/flushall',(req, res) =>{
	redis_flush();
	res.json({result:"OK"});

})


app.get('/p2json/:nodeset/:ident',(req, res) =>{
	var name = req.params["nodeset"];
	var shorty = req.params["ident"];
	p2json(name, shorty);
	res.json({result:"OK"});

})

app.get('/list_projects', (req, res) => { //reacts to requests -> /list_projects
	const output = execSync("cd .. && cd Projects && ls", { encoding: 'utf-8' });
	var out = output.split("\n");
	if(out[out.length-1] === ""){
		out.splice(-1,1);
		}
	console.log("Response: ", out);
	res.json({result:out});
	})
	
app.get('/list_nodesets', (req, res) => { //reacts to requests -> /list_nodesets
	const output = execSync("cd .. && cd nodesets && ls", { encoding: 'utf-8' });
	var out = output.split("\n");
	var result = [];
	for(let i = 0; i < out.length; i++){
		if(out[i].includes(".xml")){
			result.push(out[i]);
			}
		}
	console.log("Response: ", result);
	res.json({result:result});
	})


app.get('/new_project', (req, res) => { //reacts to requests -> /new_project?name=myproject
	const name = req.query.name; //project name
	const output = execSync("cd .. && cd Projects && ls", { encoding: 'utf-8' });
	var out = output.split("\n");
	var result = "";
	var err = "Error - Project already exists.";
	for(let i = 0; i < out.length; i++){
		if(out[i] === name){
			return res.json({result:err});
			}
		}
	const dir = execSync("cd .. && cd Projects && mkdir "+name, { encoding: 'utf-8' });
	
	var cp = execSync("sudo cp /home/pi/ModelingTool/nodesets/Opc.Ua.NodeSet2.xml /home/pi/ModelingTool/Projects/"+name+"/Opc.Ua.NodeSet2.xml", { encoding: 'utf-8' });
	cp = execSync("sudo cp /home/pi/ModelingTool/nodesets/Opc.Ua.NodeSet2.json /home/pi/ModelingTool/Projects/"+name+"/Opc.Ua.NodeSet2.json", { encoding: 'utf-8' });
	const cur_dir = execSync("cd .. && cd Projects && cd "+name+" && ls", { encoding: 'utf-8' });
	console.log("New Project was created.");
	res.json({result:cur_dir});
	})
	

app.get('/save_project', (req, res) => { //reacts to requests -> /save_project?name=myproject
	const name = req.query.name; //project name
	const output = execSync("sudo cp /var/www/html/root.json /home/pi/ModelingTool/Projects/"+name+"/"+name+".json", { encoding: 'utf-8' });
	console.log("Project "+name+" was saved.");
	res.json({result:"Project saved"});
	})
	

app.get('/load_json', (req, res) => { //reacts to requests -> /load_json?name=myproject
	const name = req.query.name; //project name
	var output = execSync("cd .. && cd Projects && ls", { encoding: 'utf-8' });
	var out = output.split("\n");
	var result = "";
	var err = "Error - Project or file not available.";
	for(let i = 0; i < out.length; i++){
		if(out[i] === name){
				var output1 = execSync("cd .. && cd Projects && cd "+name+" && ls", { encoding: 'utf-8' });
				var out1 = output1.split("\n");
				var chk = name+".json"
					for(let y = 0; y < out1.length; y++){
						if(out1[y] === chk){
							result = execSync("sudo cp /home/pi/ModelingTool/Projects/"+name+"/"+name+".json /var/www/html/root.json", { encoding: 'utf-8' });
							console.log("Project has been loaded.");
							return res.json({result:"Project loaded"});
							}
						}
			}
		}
	
	res.json({result:err});
	})
	
	
app.get('/root', (req, res) => { //reacts to requests -> /root
	console.log("Return root.");
	res.json([{id:"i=84",text:"Root",children:[{id:"i=85",text:"Objects",children:true},{id:"i=86",text:"Types", icon : "/variable_node.svg", children:true},{id:"i=87",text:"View",children:false}]}]);
})


function isChildRef(obj){
	if('IsForward' in obj && obj.IsForward === 'false'){
		return false;
	}
	if('IsForward' in obj && obj.IsForward === 'true'){
		switch (obj.ReferenceType) {
			case 'Organizes': return true; 
			case 'HasComponent': return true;
			case 'HasProperty': return true;
			case 'HasAddIn': return true;
			case 'HasSubtype': return true;
			default: return false;
		}
	}
	switch (obj.ReferenceType) {
			case 'Organizes': return true; 
			case 'HasComponent': return true;
			case 'HasProperty': return true;
			case 'HasAddIn': return true;
			case 'HasSubtype': return true;
			default: return false;
		}
	

	return false;
}

function checkDouble(item, obj){
	for(let i = 0; i < obj.length; i++){
		if(item.id === obj[i].id){
			return true;
		}
	}
	return false;
}
/*
app.get('/lazy', (req, res) => { 
	//console.log(req);
	var ret_obj = [];
	let node = {};
	if(req.query.id == "#"){
		//res.json([{id:"i=84",text:"Root",data:{nodeclass:"Object"},children:true}]);
		res.json([{id:"i=84",text:"Root",data:{nodeclass:"Object", idx:0},children:[{id:"i=85",text:"Objects",data:{nodeclass:"Object", idx:0},children:true},{id:"i=86",text:"Types", data:{nodeclass:"Object", idx:0},children:true},{id:"i=87",text:"View",data:{nodeclass:"Object", idx:0},children:true}]}]);
	}
	var nid = req.query.id;
	node = searchNode(nid);
	console.log(node);

	if(node.data.references != null){
		console.log("Here:"+node.data.references);
		if(Array.isArray(node.data.references.Reference)){
			console.log("And:"+node.data.references.Reference);
			for(let x = 0; x < node.data.references.Reference.length; x++ ){
				if(isChildRef(node.data.references.Reference[x])){
					var cnode = searchNode(node.data.references.Reference[x].$t);
					if(!checkDouble(cnode,ret_obj)){
						ret_obj.push(cnode);
					}
				}
			}
			
		}else{
			console.log("But:"+node.data.references);
			if(isChildRef(node.data.references)){
					var cnode = searchNode(node.data.references.$t);
					if(!checkDouble(cnode,ret_obj)){
								ret_obj.push(cnode);
							}
				}
		}
	}
	getAllChildren(nid, ret_obj);
	console.log(ret_obj);
	res.json(ret_obj);
});
*/


app.get('/lazy', async function(req, res) { 
	var ret_obj = [];
	let node = {};
	if(req.query.id == "#"){
		res.json([{id:"i=84",text:"Root",data:{nodeclass:"Object", nsindex:0},children:[{id:"i=85",text:"Objects",data:{nodeclass:"Object", nsindex:0},children:true},{id:"i=86",text:"Types", data:{nodeclass:"Object", nsindex:0},children:true},{id:"i=87",text:"View",data:{nodeclass:"Object", nsindex:0},children:true}]}]);
		return 0;
	}
	
	var nid = req.query.id;
	var idx = req.query.nsindex;
	var classn = req.query.nodeclass;
	var class_name = "";
		switch(classn){
			case "ObjectType": class_name="objecttypes"; break; 
			case "Object": class_name="objects"; break;
			case "VariableType": class_name="variabletypes"; break;
			case "DataType": class_name="datatypes"; break;
			case "ReferenceType": class_name="referencetypes"; break;
			case "Variable": class_name="variables"; break;
			case "Method": class_name="methods"; break;
			default: class_name="objects";
		}
	var obj = await getThisNode(idx, nid, class_name);
	//console.log(obj);
	
	var ch = await getChildrenSql(idx, obj.id);
	//console.log(ch);
	for(let j = 0; j < ch.length; j++){
		classn = ch[j][2];
		switch(classn){
			case "ObjectType": class_name="objecttypes"; break; 
			case "Object": class_name="objects"; break;
			case "VariableType": class_name="variabletypes"; break;
			case "DataType": class_name="datatypes"; break;
			case "ReferenceType": class_name="referencetypes"; break;
			case "Variable": class_name="variables"; break;
			case "Method": class_name="methods"; break;
			default: class_name="objects";
		}
		console.log(ch[j][1]+","+ch[j][0]+","+class_name);
		var ch0 = await getThisNode(ch[j][1],ch[j][0],class_name);
		console.log(ch0);
	}
	//console.log(ch);
	
	
	
	
	
	
	
	
	
	node = searchNode(nid);
	//console.log(node);

	if(node.data.references != null){
		//console.log("Here:"+node.data.references);
		if(Array.isArray(node.data.references.Reference)){
			//console.log("And:"+node.data.references.Reference);
			for(let x = 0; x < node.data.references.Reference.length; x++ ){
				if(isChildRef(node.data.references.Reference[x])){
					var cnode = searchNode(node.data.references.Reference[x].$t);
					if(!checkDouble(cnode,ret_obj)){
						ret_obj.push(cnode);
					}
				}
			}
			
		}else{
			//console.log("But:"+node.data.references);
			if(isChildRef(node.data.references)){
					var cnode = searchNode(node.data.references.$t);
					if(!checkDouble(cnode,ret_obj)){
								ret_obj.push(cnode);
							}
				}
		}
	}
	getAllChildren(nid, ret_obj);
	//console.log(ret_obj);
	res.json(ret_obj);
});


app.get('/index/:ns1/:ns2', (req, res) => { 
	var n1 = req.params["ns1"];
	var n2 = req.params["ns2"];
	var num = getIndexObj(ns_array[n1][0],ns_array[n2][0]);
	console.log(getNode(ns_array[3][0],2,15048));
	res.send("Index of "+ns_array[n2][1]+' in '+ns_array[n1][1]+' is '+num);
});


app.get('/test/:id', (req, res) => { //test
	var n1 = parseInt(req.params["id"]);
	console.log(ns_array[n1][1],);
	var ret = searchNode("i=85");
	console.log(ret);
	res.send("All good");
	//res.json([{id:"i=84",text:"Root",children:[{id:"i=85",text:"Objects",children:true},{id:"i=86",text:"Types", children:true},{id:"i=87",text:"View",children:false}]}]);
})

app.get('/require/all', (req, res) => { //test
	ns_array.push([jsn, "base", jsn.UANodeSet.Models.Model.ModelUri]);
	ns_array.push([di, "di", di.UANodeSet.Models.Model.ModelUri]);
	ns_array.push([ia, "ia", ia.UANodeSet.Models.Model.ModelUri]);
	ns_array.push([mach, "mach", mach.UANodeSet.Models.Model.ModelUri]);
	ns_array.push([mt, "mt", mt.UANodeSet.Models.Model.ModelUri]);	
	res.json({result:"OK"});
})
	
	
app.listen(port, () => {
	console.log("Server listening at http://localhost:", port);
	})
