var JsonRpcAbstract = require("./JsonRpcAbstract.js").JsonRpcAbstract;
var Types = require("../common/Types.js");

/**
 * @class JsonRpcRequest
 * @extends JsonRpcAbstract
 * @requires JsonRpcAbstract
 *
 * @param {Object} | {String} configuration
 */
var JsonRpcRequest = exports.JsonRpcRequest = function (/*data|id, method, params*/) {
    this._id = null;
    this._method = null;
    this._params = {};

    JsonRpcAbstract.apply(this, arguments);
};

JsonRpcRequest.prototype = Object.create(JsonRpcAbstract.prototype);

JsonRpcRequest.prototype._init = function (args) {
    if (args[0]) {
        this.setId(args[0]);
    } else {
        throw JsonRpcAbstract.Exceptions.INVALID_JSON_RPC;
    }

    if (args[1]) {
        this.setMethod(args[1]);
    } else {
        throw JsonRpcAbstract.Exceptions.INVALID_JSON_RPC;
    }

    if (args[2]) {
        this.setParams(args[2]);
    }
};

JsonRpcRequest.prototype._parse = function (json) {
    if (Types.isArray(json) && json.length == 1) {
        json = json[0];
    }

    return [
        json.id,
        json.method,
        json.params
    ];
};

JsonRpcRequest.prototype.setId = function (id) {
    if (typeof id !== 'string') {
        throw "Id should be a string";
    }

    this._id = id;

    return this;
};

/**
 * returns json rpc id
 *
 * @returns {Number}
 */
JsonRpcRequest.prototype.getId = function () {
    return this._id;
};

JsonRpcRequest.prototype.setMethod = function (method) {
    if (typeof method !== 'string') {
        throw "Method should be a string";
    }

    this._method = method;

    return this;
};
/**
 * returns json rpc method parameter
 *
 * @returns {String}
 */
JsonRpcRequest.prototype.getMethod = function () {
    return this._method;
};

JsonRpcRequest.prototype.setVersion = function (version) {
    if (typeof version !== 'string') {
        throw "Version should be a string";
    }
    this._jsonrpc = version;

    return this;
};
/**
 * returns json rpc version number
 *
 * @returns {Number}
 */
JsonRpcRequest.prototype.getVersion = function () {
    return this._jsonrpc;
};

JsonRpcRequest.prototype.setParams = function (params) {
    this._params = params;

    return this;
};
/**
 * returns json rpc params data
 *
 * @returns {Object}
 */
JsonRpcRequest.prototype.getParams = function () {
    return this._params;
};

JsonRpcRequest.prototype.setParam = function (key, value) {
    if (typeof key !== 'string') {
        throw "Key should be a string";
    }

    this._params[key] = value;

    return this;
};
/**
 * returns single json rpc param
 *
 * @param {String} key
 * @returns {Object}
 */
JsonRpcRequest.prototype.getParam = function (key) {
    if (this._params.hasOwnProperty(key)) {
        return this._params[key];
    }
    return null;
};

/**
 * returns properties as json
 *
 * @returns {Object}
 */
JsonRpcRequest.prototype.toJson = function () {
    return {
        "jsonrpc": this._jsonrpc,
        "id": this._id,
        "method": this._method,
        "params": this._params
    };
};

JsonRpcRequest.prototype.toString = function () {
    return JSON.stringify(this.toJson());
};
