var JsonRpcAbstract = require("./JsonRpcAbstract.js").JsonRpcAbstract;
var JsonRpcError = require('./JsonRpcError.js').JsonRpcError;

/**
 * @class JsonRpcResult
 * @extends JsonRpcAbstract
 * @requires JsonRpcAbstract
 *
 * @param {Object} result
 */
var JsonRpcResponse = function (/*data|id, result, error*/) {
    this._id = null;
    this._result = null;
    this._error = null;

    JsonRpcAbstract.apply(this, arguments);
};
JsonRpcResponse.prototype = Object.create(JsonRpcAbstract.prototype);

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

    if (args[1]) {
        this.setResult(args[1]);
    }

    if (args[2]) {
        this.setError(new JsonRpcError(args[2]));
    }
};

JsonRpcResponse.prototype._parse = function (json) {
    return [
        json.id,
        json.result,
        json.error
    ];
};

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

    this._id = id;

    return this;
};

JsonRpcResponse.prototype.getId = function () {
    return this._id;
};

/**
 * sets result
 * 
 * @param {Object} result
 * @returns {JsonRpcResult}
 */
JsonRpcResponse.prototype.setResult = function (result) {
    this._result = result;

    return this;
};

/**
 * gets result
 * 
 * @returns {Object}
 */
JsonRpcResponse.prototype.getResult = function () {
    return this._result;
};

JsonRpcResponse.prototype.setError = function (code, message, data) {
    if (code instanceof JsonRpcError) {
        this._error = code;
    } else {
        this._error = new JsonRpcError(code, message, data);
    }

    return this;
};

JsonRpcResponse.prototype.getError = function () {
    return this._error;
};

JsonRpcResponse.prototype.isError = function () {
    return this._error !== null;
};

/**
 * returns properties as json
 * 
 * @returns {Object}
 */
JsonRpcResponse.prototype.toJson = function () {
    var jsonObj = {
        jsonrpc: this._jsonrpc,
        id: this._id,
        result: this._result
    };

    if (this._error) {
        jsonObj.error = this._error.toJson();
    }

    return jsonObj;
};

exports.JsonRpcResponse = JsonRpcResponse;