const crypt = require("../crypt");

function parseRq (bytes) {
	try {
		return JSON.parse(bytes.toString());
	} catch (e) {
		return undefined;
	}
}

class APIMethods {
	constructor (parent) {
		this.parent = parent;
	}
	
	info (_, ___, __, cb) {
		cb({ result: require("./server-info") });
	}
	
	/*setSession (isEncrypted, address, { key, counter }, cb) {
		if (!global.config.server.secureMode)
			return cb({ error: "Encryption is off by configuration file into server" });
		if (!isEncrypted)
			return cb({ error: "Encryption required" });
		try {
			this.parent.sessions[address] = new crypt.AES(key, counter);
			return cb({ result: "Session key installed" });
		} catch (err) {
			return cb({ error: "Invalid params. Must be key and counter" });
		}
	}*/
}

class API {
    constructor () {
		this.methods = new APIMethods(this);
		this.sessions = {};
    }
	
	decrypt (address, bytes) {
		try {
			if (!global.config.server.secureMode)
				// return Buffer.from([]);
				return undefined;
			if (!this.sessions[address])
				return global.openSSH.decrypt(bytes);
			else
				this.sessions[address].decrypt(bytes);
		} catch (err) {
			return undefined;
		}
	}
	
    async exec (address, bytes, cb) {
		const request = parseRq(bytes);
		
		if (request === undefined)
			return cb({
				error: "required JSON object request"
			});
		
		if (typeof request === "object" && request !== null) {
			const {
				method
			} = request;
			this.methods[method]?.(false, address, request, cb);
		} else {
			return cb({
				error: "required JSON-object based request"
			});
		}
    }
}

module.exports = { API };
