'use strict';

// set paperspace_cli to see if we are being run at the command line
// note: there are four typical entry points to the library: bin/paperspace, lib/paperspace.js, index.js, and lib/cli.js
if (!global.paperspace_cli) global.paperspace_cli = (require.main === module);

// Native
var argv = require('yargs').argv;

// Convert arg values that look boolean to boolean
for (var arg in argv) {
	if (arg !== '$0' && typeof argv[arg] === 'string') {
		var val = argv[arg];
		if (val === 'true' || argv[arg] === 'false') {
			argv[arg] = (val === 'true');
		}
	}
}

var givenNamespace = argv._[0];
var givenName = argv._[1];

// Packages
var chalk = require('chalk');

// Ours
var paperspace = require('./../lib/paperspace');

var DEETS_NOTE = 'See https://paperspace.github.io/paperspace-node for details';

function methodHint(spec) {
	return [
		'Usage:',
		'  paperspace ' + spec.method.group + ' ' + spec.name,
		'',
		DEETS_NOTE,
	].join('\n');
}

function methodHints() {
	var namespaces = {};

	paperspace.eachEndpoint(function _each(namespace, name, method) {
		if (!namespaces[namespace]) namespaces[namespace] = [];
		namespaces[namespace].push(name);
	});

	var hints = '';

	for (var namespace in namespaces) {
		hints += '\t  ' + namespace + '\n';

		var names = namespaces[namespace];

		names.forEach(function(name) {
			hints += '\t    ' + name + '\n';
		});
	}

	return hints;
}

if (!givenNamespace && !givenName) {
	console.log();
	console.log('    ' + chalk.bold('paperspace') + ' <namespace> <command> [...flags]');
	console.log();
	console.log('    ' + chalk.dim('Commands:'));
	console.log();
	console.log('    ' + methodHints());
	console.log();
	console.log('    ---');
	console.log('    ' + chalk.dim(DEETS_NOTE));
	console.log('');

	process.exit();
}

var foundMethod;

paperspace.eachEndpoint(function _each(namespace, name, method) {
	if (namespace === givenNamespace && name == givenName) {
		foundMethod = {
			namespace: namespace,
			name: name,
			method: method,
		};
	}
});

if (!foundMethod) {
	console.error('No such command `' + givenNamespace + ' ' + givenName + '`');
	process.exit(1);
}

if (argv.help) {
	console.log(methodHint(foundMethod));
	process.exit();
}

function safeJSON(obj) {
	try {
		if (obj instanceof Array) return JSON.stringify(obj, null, 2) + '\n';
		else return JSON.stringify(obj, Object.getOwnPropertyNames(obj), 2) + '\n';
	} catch (err) {
		console.error(err);
		return '{}';
	}
}

foundMethod.method(argv, function _methodCb(methodErr, methodResp) {
	if (methodErr) {
		process.stdout.write(
			safeJSON({
				error: methodErr.error || methodErr.message,
				status: methodResp && methodResp.statusCode,
				response: methodResp && methodResp.body,
			})
		);

		process.exit(1);
	}
	// if content is gzipped, then body is empty object, and content is in 'text'
	if (methodResp && methodResp.text) {
		try {
			methodResp.body = JSON.parse(methodResp.text);
		} catch (err) {
			console.error(err);
			methodResp.body = {};
		}
	}
	if (methodResp != null)	process.stdout.write(safeJSON(methodResp.body || {})); // null means suppress output here
});

@@ -2266,65 +2266,14 @@
 eof 
-Array) return JSON.stringify(obj, null, 2) + '%5Cn';%0A%09%09else
+Error)
  ret
@@ -2340,16 +2340,67 @@
 + '%5Cn';%0A
+%09%09else return JSON.stringify(obj, null, 2) + '%5Cn';%0A
 %09%7D catch
@@ -2544,54 +2544,163 @@
 %7B%0A%09%09
-process.stdout.write(%0A%09%09%09safeJSON(%7B%0A%09%09%09%09error:
+var errorSummary = %7B%0A%09%09%09error: (methodErr.response && methodErr.response.body && methodErr.response.body.error && methodErr.response.body.error.message) %7C%7C
  met
@@ -2737,17 +2737,16 @@
 age,%0A%09%09%09
-%09
 status: 
@@ -2755,51 +2755,131 @@
 thod
-Resp && methodResp.statusCode,%0A%09%09%09%09
+Err.response && methodErr.response.statusCode %7C%7C statusmethodErr.status,%0A%09%09%7D;%0A%09%09if (!global.paperspace_cli) errObj.
 response
 : me
@@ -2878,49 +2878,77 @@
 onse
-:
+ =
  method
-Resp && methodResp.body,%0A%09%09%09%7D)%0A%09%09
+Err.response;%0A%0A%09%09process.stdout.write(safeJSON(errorSummary)
 );%0A%0A

fix error reporting to show inner error message first, and eliminate response when in command line mode; also fix issue parsing non-Error objects in safeJSON()