import { default as bcrypt } from 'bcrypt';
const saltRounds = 10;
import { default as programa } from 'commander';
import { default as restify } from 'restify-clients';
import * as util from 'util';

var port_cliente;
var host_cliente;
var version_cliente = '*';
var prot_cliente;
var idauten = 'them';
var codigoaut = 'D4ED43C0-8BD6-4FE2-B358-7C0E230D11EF';

async function hashClave(clave) {
	let salt = await bcrypt.genSalt(saltRounds);
	let hasheado = await bcrypt.hash(clave, salt);
	return hasheado;
}

const cliente = (programa) => {
	if (typeof process.env.PORT === 'string')
		port_cliente = Number.parseInt(process.env.PORT);
        if (typeof programa.PORT === 'string')
                port_cliente = Number.parseInt(programa.PORT);
	if (typeof programa.host === 'string') host_cliente = programa.host;
	if (typeof programa.url === 'string') {
		let purl = new URL(programa.url);
		if (purl.host && purl.host !=='') host_cliente = purl.host;
		if (purl.port && purl.port !=='') port_cliente = purl.port;
		if (purl.protocol && purl.protocol !== '')
			prot_cliente = purl.protocol;
	}
	let url_conectar = new URL('http://127.0.0.1:5858');
	if (prot_cliente) url_conectar.protocol = prot_cliente;
	if (host_cliente) url_conectar.host = host_cliente;
	if (port_cliente) url_conectar.port = port_cliente;
	let cliente = restify.createJsonClient({
		url: url_conectar.href,
		version: version_cliente
	});
	cliente.basicAuth(idauten, codigoaut);
	return cliente;
}

programa
	.option('-p, --port <puerto>',
		'Numero de Puerto del server si usa localhost')
	.option('-h, --host <host>',
		'Direccion de host si usa local')
	.option('-u, --url <url>',
		'URL de conexion al server si usamos uno remoto');

programa
	.command('add <usuario>')
	.description('Agrega un usuario al servidor')
	.option('--password <password>', 'Conntraseña del usuario')
	.option('--apellido <apellido>', 'Apellido del usuario')
	.option('--nombre <nombre>', 'Nombre del usuario')
	.option('--email <email>', 'direccion de correo del usuario')
	.action(async (usuario, cmdObj) => {
		const subir = {
			usuario: usuario, 
			clave: await hashClave(cmdObj.password), 
			proveedor: "local",
			apellido: cmdObj.apellido,
			nombre: cmdObj.nombre,
			email: [],
			foto: []
		};
		if (typeof cmdObj.email !== 'undefined')
			subir.email.push(cmdObj.email);
		cliente(programa).post('/crear', subir,
			(err, req, res, obj) => {
			if (err) console.error(err.stack);
			else console.log(util.inspect(obj) + ' creado.');
		});
	});

programa
	.command('find-or-create <usuario>')
	.description('Busca un usuario sino lo encuentra lo agrega')
	.option('--password <contraseña>', 'Contraseña para el usuario')
	.option('--nombre <nombre>', 'Nombre del usuario')
	.option('--apellido <apellido>', 'Apellido del usuario')
	.option('--email <email>', 'Direccion de correo del usuario')
	.action(async (usuario, cmdObj) => {
                const subir = {
                        usuario: usuario,
                        clave: await hashClave(cmdObj.password),
                        proveedor: "local",
                        apellido: cmdObj.apellido,
                        nombre: cmdObj.nombre,
                        email: [],
                        foto: []
                };
                if (typeof cmdObj.email !== 'undefined')
                        subir.email.push(cmdObj.email);
                cliente(programa).post('/buscar-o-crear', subir,
                        (err, req, res, obj) => {
                        if (err) console.error(err.stack);
                        else console.log('Se encontro o creo a ' +
				util.inspect(obj));
                });
        });

programa
	.command('find <usuario>')
	.description('Busca un usuario en el servidor')
	.action((usuario, cmdObj) => {
		cliente(programa).get(`/buscar/${usuario}`,
			(err, req, res, obj) => {
			if (err) console.error(err.stack);
			else console.log("Encontrado " +
				util.inspect(obj));
		});
	});

programa
	.command('list-users')
	.description('Listar todos los usuarios del server')
	.action((cmdObj) => {
		cliente(programa).get('/listar', 
			(err, req, res, obj) => {
			if (err) console.error(err.stack);
			else console.log(obj);
		});
	});

programa
	.command('update <usuario>')
	.description('Modifica o agrega un usuario del server')
	.option('--password <contraseña>', 'Contraseña para el usuario')
	.option('--nombre <nombre>', 'Nombre del usuario')
	.option('--apellido <apellido>', 'Apellido del usuario')
	.option('--email <email>', 'Direccion de correo del usuario')
	.action(async (usuario, cmdObj) => {
                const subir = {
                        usuario: usuario,
                        clave: await hashClave(cmdObj.password),
                        proveedor: "local",
                        apellido: cmdObj.apellido,
                        nombre: cmdObj.nombre,
                        email: [],
                        foto: []
                };
                if (typeof cmdObj.email !== 'undefined')
                        subir.email.push(cmdObj.email);
		cliente(programa).post(`/cambiar/${usuario}`, subir,
			(err, req, res, obj) => {
			if (err) console.error(err.stack)
			else console.log(util.inspect(obj) + 'Modificado');
		});
	});

programa
	.command('del <usuario>')
	.description('Elimina un usuario de la base')
	.action((usuario, cmdObj) => {
		cliente(programa).del(`/borrar/${usuario}`,
			(err, req, res, obj) => {
			if (err) console.log(err.stack);
			else console.log('Se elimino - ' + 
				util.inspect(obj));
		});
	});

programa
	.command('pwd-chk <usuario> <contraseña>')
	.description('Permite chequear la contraseña de un usuario')
	.action((usuario, clave, cmdObj) => {
		cliente(programa).post('/chequear', {usuario, clave},
			(err, req, res, obj) => {
			if (err) console.log(err.stack);
			else console.log(obj);
		});
	});

programa.parse(process.argv);
