classes/command.js

'use strict';

const SafeBuffer = require('safe-buffer').Buffer;

/**
 * @class
 * @description The base class for all commands
 */

class Command {
	/**
	 * @description The command name
	 * @type {String}
	 */
	get name() {
		return this.constructor.name;
	}

	/**
	 * @description The args passed in from K4Model
	 * @type {Object}
	 */
	set args(args) {
		this._args = args;
	}

	get args() {
		return this._args;
	}

	/**
	 * @description Returns true if commands is nested and supports commands() function
	 * @type {Boolean}
	 */
	get nested() {
		return (typeof this.commands === 'function');
	}


	/**
	 * @description The device the command was sent to
	 * @type {Device}
	 */
	set device(device) {
		this._device = device;
	}

	get device() {
		return this._device;
	}

	/**
	 * @description The adapter instance
	 * @type {Adapter}
	 */
	set adapter(adapter) {
		this._adapter = adapter;
	}

	get adapter() {
		return this._adapter;
	}

	/**
	 * @description The header (if any) for this command.
	 * Can either be a Buffer or an Object whose 'packet' field is a Buffer
	 * containing the relevant header data.
	 * @type {Buffer|Object}
	 */
	get header() {
		return this._header;
	}

	/**
	 * @description The command body.
	 * @type {Buffer}
	 */
	get body() {
		return this._body;
	}

	/**
	 * @method commands
	 * @memberof Command
	 * @description Return a promise chain of nested commands. buildBody() will not be called if commands() exists
	 * @returns {Promise}
	 * @instance
	 * @abstract
	 */

	/**
	 * @description Builds a data buffer for the command, and assigns it to the
	 * body property of this Command object.
	 * @returns {Buffer}
	 * @abstract
	 */
	buildBody() {
		throw new Error('Must be implemented by subclass!');
	}

	/**
	 * @description Builds a header for the command, and assigns it to the
	 * header property of this Command object.
	 * @returns {Buffer|Object}
	 * @abstract
	 */
	buildHeader() {
		throw new Error('Must be implemented by subclass!');
	}

	/**
	 * @description Optionally build a response object
	 * @param {Response} response The command response
	 * @returns {Object} Object to return to the model
	 * @abstract
	 */
	response(response) {
		throw new Error('Must be implemented by subclass!');
	}
};

module.exports = Command;