const fs = require( 'fs-extra' );
const path = require( 'path' );
const dnsSync = require( 'dns-sync' );
const Mustache = require( 'mustache' );

const Setup = {};

if( !fs.existsSync( '/etc/nginx/nginx.conf' ) ) {
	logger.info( '\x1b[31m Check documentation, nginx have to be installed on this server first, no /etc/nginx/nginx.conf available' );
	process.exit();
}
if( !fs.existsSync( '../config.js' ) ) {
	logger.info( `\x1b[42m####################################\nWellcome into apixtribe, this is a first install.\nWe need to make this server accessible from internet subdomain.domain to current IP. This setup will create your unique tribeid, with an admin login user to let you connect to the parameter interface.\nCheck README's project to learn more. more.\n#####################################\x1b[0m` );
	const confdata = fs.readJsonSync( path.normalize( `${__dirname}/../setup/configsetup.json` ) );
	logger.info( 'Current setup conf from :\n' + path.normalize( `${__dirname}/../setup/configsetup.json` + '\nChange with relevant setup data and rerun yarn setup' ) );
	logger.info( confdata )
	const readline = require( 'readline' );
	const rl = readline.createInterface( {
		input: process.stdin,
		output: process.stdout
	} );

	rl.question( 'This is the data from setup/configsetup.json used, is it correct to use as first install (Yes/no)?', function ( rep1 ) {
		let quest = `This is a production install, please check that ${confdata.subdomain}.${confdata.domain} IP is well redirect to tour server`;
		if( rep1 !== "Yes" ) process.exit( 0 );
		if( confdata.domain == 'local.fr' ) {
			quest = `This is a development installation, please add in your /etc/hosts "127.0.0.1 ${confdata.subdomain}.${confdata.domain} " `;
		}
		rl.question( quest + '\nAre you sure to set this? (Yes/no)', function ( rep2 ) {
			if( rep2 == "Yes" ) {
				const check = Setup.checkdata( confdata );
				if( check == "" ) {
					Setup.config( confdata );
				} else {
					logger.info( check );
				}
			} else {
				logger.info( 'Nothing done please, check setup/configsetup.json and  answer twice Yes' )
			}
			rl.close();
		} );
	} );
	rl.on( 'close', function () {
		logger.info( '\n Setup process ended' );
		process.exit( 0 );
	} );
} else {
	logger.info( 'Carefull you have already a config.js that is running. If you want to change remove config.js file and run again yarn setup' );
}

Setup.checkdata = conf => {
	let rep = "";
	if( ![ 'dev', 'prod' ].includes( conf.mode ) ) {
		rep += "mode have to be 'dev' or 'prod' currently it's " + conf.mode + "\n";
	}
	conf.language.forEach( l => {
		if( ![ "fr", "en", "it", "de", "sp" ].includes( l ) ) {
			rep += l + " Only fr,en,it,de,sp are available \n";
		}
	} );
	if( !fs.existsSync( `/home/${conf.linuxuser}` ) ) {
		rep += `/home/${conf.linuxuser} does not exist, user has to be create with a /home on this server\n`;
	}
	// avant eslint if( !( /^[a-z\s\-]+$/.test( conf.druidid ) ) ) {
	if( !( /^[a-z\s-]+$/.test( conf.druidid ) ) ) {
		rep += `${conf.druidid} have to contain only a-z characters `;
	}
	// add a check later have to be unique if not in dev
	if( !( /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&.])[A-Za-z\d$@$!%*?&.{}:|\s]{8,}/.test( conf.genericpsw ) ) ) {
		rep += "Give a generic pasword for all your tribeid's user,they will change it min 8 char special char upper lower case and number"
	}
	if( conf.jwtsecret.length < 32 ) {
		rep += "Your jwtsecretkey must have at least 32 characters"
	}
	if( conf.mode != 'dev' && !dnsSync.resolve( `${conf.subdomain}.${conf.domain}` ) ) {
		rep += `\nresolving ${conf.subdomain}.${conf.domain} will not responding valid IP, please setup domain redirection IP before runing this script`
	}
	return rep
};
Setup.config = ( confdata ) => {
	// Init this instance with a .config.js
	Setup.configjs( confdata );
	// Create tribeid space + a user admin + webspace withe apixtribe webapp install
	Setup.druidid( confdata );
};
Setup.configjs = ( confdata ) => {
	// Set /config.js
	let confapixtribe = fs.readFileSync( './setup/config.mustache', 'utf-8' );
	fs.writeFileSync( './config.js', Mustache.render( confapixtribe, confdata ), 'utf-8' );
	if( fs.existsSync( './config.js' ) ) {
		logger.info( 'config.js successfully created.' );
	} else {
		logger.info( "config.js not created, check what's wrong in tpl:", confapixtribe );
		logger.info( "for data :", confdata );
		process.exit();
	}
};
Setup.druidid = ( confdata ) => {
	// create a tribeid with a user that will admin this instance into /tribes/tribeid /users
	const config = require( '../config.js' );
	// Need to do it on setup this is also done again in models/Tribes.js
	logger.info( `${config.tribes}/${confdata.druidid}` )
	fs.ensureDirSync( `${config.tribes}/${confdata.druidid}` );
		[ 'users', 'www', 'referentials', 'nationchains' ].forEach( r => {
		fs.copySync( `${config.mainDir}/setup/tribes/apixtribe/${r}`, `${config.tribes}/${confdata.druidid}/${r}` );
	} )
	/*	const confcli = JSON.parse( Mustache.render( fs.readFileSync( `${config.mainDir}/setup/tribes/apixtribe/clientconf.mustache`, 'utf8' ), confdata ) );
		fs.outputJsonSync( `${config.tribes}/${confdata.druidid}/clientconf.json`, confcli );
		// Create a new tribeid + admin user for this tribeid
		// with access to {druidid}:webapp as admin
		*/
	const Tribes = require( '../models/Tribes.js' );
	const access = { app: {}, data: {} }
	access.app[ `${confdata.druidid}:webapp` ] = "admin";
	access.data[ confdata.druidid ] = { "users": "CRUDO", "referentials": "CRUDO", "www": "CRUDO" };
	const createclient = Tribes.create( {
		tribeid: confdata.druidid,
		genericpsw: confdata.genericpsw,
		lanquageReferential: confdata.language,
		useradmin: {
			LOGIN: confdata.login,
			xlang: confdata.language[ 0 ],
			ACCESSRIGHTS: access
		}
	} );
	if( createclient.status == 200 ) {
		logger.info( `Your tribeid domain was created with login : ${confdata.login} and password: ${confdata.genericpsw}, change it after the 1st login on https://${confdata.subdomain}.${confdata.domain}` );
		// Create nginx conf for a first install
		const confnginx = fs.readFileSync( './setup/nginx/nginx.conf.mustache', 'utf8' );
		fs.outputFileSync( '/etc/nginx/nginx.conf', Mustache.render( confnginx, confdata ), 'utf-8' );
		// Create a spacedev for webapp of apixtribe
		// that will be accesible in prod from https://subdomain.domain/ and in dev http://webapp.local.fr
		const addspaceweb = Tribes.addspaceweb( {
			setup: true,
			dnsname: [ `${confdata.subdomain}.${confdata.domain}` ],
			mode: confdata.mode,
			tribeid: confdata.druidid,
			website: 'webapp',
			pageindex: "app_index_fr.html"
		} );
		if( addspaceweb.status == 200 ) {
			logger.info( `WELL DONE run yarn dev to test then yarn startpm2 ` )
		}
	} else {
		logger.info( 'Issue ', createclient )
	}
}

module.exports = Setup;
