text: var path = require('path');
  var fs = require('fs');
  var util = require('util');
  var hfc = require('fabric-client');
  var Peer = require('fabric-client/lib/Peer.js');
  var EventHub = require('fabric-client/lib/EventHub.js');
  var config = require('../config.json');
  var helper = require('./helper.js');
  var logger = helper.getLogger('Query');
  
  //    .aMMMb  dMP dMP dMMMMMP dMMMMb  dMP dMP 
  //   dMP"dMP dMP dMP dMP     dMP.dMP dMP.dMP  
  //  dMP.dMP dMP dMP dMMMP   dMMMMK"  VMMMMP   
  // dMP.MMP dMP.aMP dMP     dMP"AMF dA .dMP    
  // VMMP"MP VMMMP" dMMMMMP dMP dMP  VMMMP"     
                                             
  
  var queryChaincode = function(peer, channelName, chaincodeName, args, fcn, username, org) {
  	var channel = helper.getChannelForOrg(org);
  	var client = helper.getClientForOrg(org);
  	var target = buildTarget(peer, org);
  	return helper.getRegisteredUsers(username, org).then((user) => {
  		tx_id = client.newTransactionID();
  		var request = {
  			chaincodeId: chaincodeName,
  			txId: tx_id,
  			fcn: fcn,
  			args: args
  		};
  		return channel.queryByChaincode(request, target);
  	}, (err) => {
  		logger.info('Failed to get submitter \''+username+'\'');
  		return 'Failed to get submitter \''+username+'\'. Error: ' + err.stack ? err.stack :
  			err;
  	}).then((response_payloads) => {
  		if (response_payloads) {
  			for (let i = 0; i < response_payloads.length; i++) {
  				return JSON.parse(response_payloads[i].toString('utf8'));
  			}
  		} else {
  			logger.error('response_payloads is null');
  			return 'response_payloads is null';
  		}
  	}, (err) => {
  		logger.error('Failed to send query due to error: ' + err.stack ? err.stack :
  			err);
  		return 'Failed to send query due to error: ' + err.stack ? err.stack : err;
  	}).catch((err) => {
  		logger.error('Failed to end to end test with error:' + err.stack ? err.stack :
  			err);
  		return 'Failed to end to end test with error:' + err.stack ? err.stack :
  			err;
  	});
  };
  
  var getBlockByNumber = function(peer, blockNumber, username, org) {
  	var target = buildTarget(peer, org);
  	var channel = helper.getChannelForOrg(org);
  
  	return helper.getRegisteredUsers(username, org).then((member) => {
  		return channel.queryBlock(parseInt(blockNumber), target);
  	}, (err) => {
  		logger.info('Failed to get submitter "' + username + '"');
  		return 'Failed to get submitter "' + username + '". Error: ' + err.stack ?
  			err.stack : err;
  	}).then((response_payloads) => {
  		if (response_payloads) {
  			logger.debug(response_payloads);
  			return response_payloads; 
  		} else {
  			logger.error('response_payloads is null');
  			return 'response_payloads is null';
  		}
  	}, (err) => {
  		logger.error('Failed to send query due to error: ' + err.stack ? err.stack :
  			err);
  		return 'Failed to send query due to error: ' + err.stack ? err.stack : err;
  	}).catch((err) => {
  		logger.error('Failed to query with error:' + err.stack ? err.stack : err);
  		return 'Failed to query with error:' + err.stack ? err.stack : err;
  	});
  };
  
  var getTransactionByID = function(peer, trxnID, username, org) {
  	var target = buildTarget(peer, org);
  	var channel = helper.getChannelForOrg(org);
  
  	return helper.getRegisteredUsers(username, org).then((member) => {
  		return channel.queryTransaction(trxnID, target);
  	}, (err) => {
  		logger.info('Failed to get submitter "' + username + '"');
  		return 'Failed to get submitter "' + username + '". Error: ' + err.stack ?
  			err.stack : err;
  	}).then((response_payloads) => {
  		if (response_payloads) {
  			logger.debug(response_payloads);
  			return response_payloads;
  		} else {
  			logger.error('response_payloads is null');
  			return 'response_payloads is null';
  		}
  	}, (err) => {
  		logger.error('Failed to send query due to error: ' + err.stack ? err.stack :
  			err);
  		return 'Failed to send query due to error: ' + err.stack ? err.stack : err;
  	}).catch((err) => {
  		logger.error('Failed to query with error:' + err.stack ? err.stack : err);
  		return 'Failed to query with error:' + err.stack ? err.stack : err;
  	});
  };
  
  var getBlockByHash = function(peer, hash, username, org) {
  	var target = buildTarget(peer, org);
  	var channel = helper.getChannelForOrg(org);
  
  	return helper.getRegisteredUsers(username, org).then((member) => {
  		return channel.queryBlockByHash(Buffer.from(hash), target);
  	}, (err) => {
  		logger.info('Failed to get submitter "' + username + '"');
  		return 'Failed to get submitter "' + username + '". Error: ' + err.stack ?
  			err.stack : err;
  	}).then((response_payloads) => {
  		if (response_payloads) {
  			logger.debug(response_payloads);
  			return response_payloads;
  		} else {
  			logger.error('response_payloads is null');
  			return 'response_payloads is null';
  		}
  	}, (err) => {
  		logger.error('Failed to send query due to error: ' + err.stack ? err.stack :
  			err);
  		return 'Failed to send query due to error: ' + err.stack ? err.stack : err;
  	}).catch((err) => {
  		logger.error('Failed to query with error:' + err.stack ? err.stack : err);
  		return 'Failed to query with error:' + err.stack ? err.stack : err;
  	});
  };
  
  var getChainInfo = function(peer, username, org) {
  	var target = buildTarget(peer, org);
  	var channel = helper.getChannelForOrg(org);
  
  	return helper.getRegisteredUsers(username, org).then((member) => {
  		return channel.queryInfo(target);
  	}, (err) => {
  		logger.info('Failed to get submitter "' + username + '"');
  		return 'Failed to get submitter "' + username + '". Error: ' + err.stack ?
  			err.stack : err;
  	}).then((blockchainInfo) => {
  		if (blockchainInfo) {
  			logger.debug('===========================================');
  			logger.debug(blockchainInfo.currentBlockHash);
  			logger.debug('===========================================');
  			return blockchainInfo;
  		} else {
  			logger.error('response_payloads is null');
  			return 'response_payloads is null';
  		}
  	}, (err) => {
  		logger.error('Failed to send query due to error: ' + err.stack ? err.stack :
  			err);
  		return 'Failed to send query due to error: ' + err.stack ? err.stack : err;
  	}).catch((err) => {
  		logger.error('Failed to query with error:' + err.stack ? err.stack : err);
  		return 'Failed to query with error:' + err.stack ? err.stack : err;
  	});
  };
  //getInstalledChaincodes
  var getInstalledChaincodes = function(peer, type, username, org) {
  	var target = buildTarget(peer, org);
  	var channel = helper.getChannelForOrg(org);
  	var client = helper.getClientForOrg(org);
  
  	return helper.getOrgAdmin(org).then((member) => {
  		if (type === 'installed') {
  			return client.queryInstalledChaincodes(target);
  		} else {
  			return channel.queryInstantiatedChaincodes(target);
  		}
  	}, (err) => {
  		logger.info('Failed to get submitter "' + username + '"');
  		return 'Failed to get submitter "' + username + '". Error: ' + err.stack ?
  			err.stack : err;
  	}).then((response) => {
  		if (response) {
  			if (type === 'installed') {
  				logger.debug('<<< Installed Chaincodes >>>');
  			} else {
  				logger.debug('<<< Instantiated Chaincodes >>>');
  			}
  			var details = [];
  			for (let i = 0; i < response.chaincodes.length; i++) {
  				logger.debug('name: ' + response.chaincodes[i].name + ', version: ' +
  					response.chaincodes[i].version + ', path: ' + response.chaincodes[i].path
  				);
  				details.push('name: ' + response.chaincodes[i].name + ', version: ' +
  					response.chaincodes[i].version + ', path: ' + response.chaincodes[i].path
  				);
  			}
  			return details;
  		} else {
  			logger.error('response is null');
  			return 'response is null';
  		}
  	}, (err) => {
  		logger.error('Failed to send query due to error: ' + err.stack ? err.stack :
  			err);
  		return 'Failed to send query due to error: ' + err.stack ? err.stack : err;
  	}).catch((err) => {
  		logger.error('Failed to query with error:' + err.stack ? err.stack : err);
  		return 'Failed to query with error:' + err.stack ? err.stack : err;
  	});
  };
  var getChannels = function(peer, username, org) {
  	var target = buildTarget(peer, org);
  	var channel = helper.getChannelForOrg(org);
  	var client = helper.getClientForOrg(org);
  
  	return helper.getRegisteredUsers(username, org).then((member) => {
  		return client.queryChannels(target);
  	}, (err) => {
  		logger.info('Failed to get submitter "' + username + '"');
  		return 'Failed to get submitter "' + username + '". Error: ' + err.stack ?
  			err.stack : err;
  	}).then((response) => {
  		if (response) {
  			logger.debug('<<< channels >>>');
  			var channelNames = [];
  			for (let i = 0; i < response.channels.length; i++) {
  				channelNames.push('channel id: ' + response.channels[i].channel_id);
  			}
  			logger.debug(channelNames);
  			return response;
  		} else {
  			logger.error('response_payloads is null');
  			return 'response_payloads is null';
  		}
  	}, (err) => {
  		logger.error('Failed to send query due to error: ' + err.stack ? err.stack :
  			err);
  		return 'Failed to send query due to error: ' + err.stack ? err.stack : err;
  	}).catch((err) => {
  		logger.error('Failed to query with error:' + err.stack ? err.stack : err);
  		return 'Failed to query with error:' + err.stack ? err.stack : err;
  	});
  };
  
  function buildTarget(peer, org) {
  	var target = null;
  	if (typeof peer !== 'undefined') {
  		let targets = helper.newPeers([peer], org);
  		if (targets && targets.length > 0) target = targets[0];
  	}
  
  	return target;
  }
  
  exports.queryChaincode = queryChaincode;
  exports.getBlockByNumber = getBlockByNumber;
  exports.getTransactionByID = getTransactionByID;
  exports.getBlockByHash = getBlockByHash;
  exports.getChainInfo = getChainInfo;
  exports.getInstalledChaincodes = getInstalledChaincodes;
  exports.getChannels = getChannels;
  