const bcrypt = require( 'bcrypt' );
const fs = require( 'fs-extra' );
const path = require( 'path' );
const jsonfile = require( 'jsonfile' );
const glob = require( 'glob' );
const jwt = require( 'jwt-simple' );
const moment = require( 'moment' );
const axios = require( 'axios' );
const UUID = require( 'uuid' );
const Outputs = require( './Outputs.js' );
const config = require( '../tribes/townconf.js' );
const checkdata = require( `../nationchains/socialworld/contracts/checkdata.js`);
/*
Blockchain manager
* Manage network directory
* read Blockchain and search,
* submit a transaction (now) or contract (futur) to store from userA.pubkey to userB.pubkey a number of AXESS
* mine to be able to register a block and create AXESS
* manage APIXP rules 20 M APIXP 1AXESS = 1 block validation
* manage contract = action if something appened validate by a proof of work
*/
const Nationchains = {};
Nationchains.init = () => {
	console.group( 'init Nationchains' );
}
Nationchains.synchronize = () => {
	/*
	    Run process to communicate with a list of apixtribe instance to update transaction and earn AXP
			To creation of a new tribeid or a new login
		*/
	//update himself then send to other information
	if( process.env.NODE_ENV != "prod" ) {
		// Not concerned
		return {}
	}
	const initcurrentinstance = {
		"fixedIP": "",
		"lastblocknumber": 0,
		"firsttimeupdate": 0,
		"lastimeupdate": 0,
		"positifupdate": 0,
		"negatifupdate": 0,
		"pubkeyadmin": "",
		"tribeids": [],
		"logins": [],
		"knowninstance": []
	};
	let currentinstance = initcurrentinstance;
	try {
		currentinstance = fs.readFileSync( `${config.tribes}/${config.mayorId}/nationchains/nodes/${config.rootURL}`, 'utf-8' )
	} catch ( err ) {
		logger.info( 'first init' )
	}
	const loginsglob = fs.readJsonSync( `${config.tmp}/loginsglob.json`, 'utf-8' );
	currentinstance.logins = Object.keys( loginsglob );
	currentinstance.tribeids = [ ...new Set( Object.values( loginsglob ) ) ];
	currentinstance.instanceknown = glob.Sync( `${config.tribes}/${config.mayorId}/nationchains/nodes/*` );
	//Save it
	fs.outputJsonSync( `${config.tribes}/${config.mayorId}/nationchains/nodes/${config.rootURL}`, currentinstance );
	// proof of work
	// try to find a key based on last block with difficulty
	// if find then send to all for update and try to get token
	// in any case rerun Nationchains.synchronize()
	currentinstance.instanceknown.forEach( u => {
		if( u != config.rootURL ) {
			//send currentinstance info and get back state of
			axios.post( `https://${u}/nationchains/push`, currentinstance )
				.then( rep => {
					newdata = rep.payload.moreinfo
					//Available update info
					fs.readJson( `${config.tribes}/${config.mayorId}/nationchains/nodes/${u}`, ( err, data ) => {
						if( err ) {
							data.negatifupdate += 1;
							data.lasttimeupdate = Date.now();
						} else {
							data.positifupdate += 1;
							data.lastimeupdate = Date.now();
							data.tribeids = newdata.tribeids;
							data.logins = newdata.logins;
							data.lastblocknumber = newdata.lastblocknumber;
							newdata.knowninstance.forEach( k => {
								if( !data.knowninstance.includes( k ) ) {
									data.knowninstance.push( k );
									//init the domain for next update
									initcurrentinstance.firsttimeupdate = Date.now();
									fs.outputJson( `${config.tribes}/${config.mayorId}/nationchains/nodes/${k}`, initcurrentinstance, 'utf-8' )
								}
							} )
						}
						//save with info
						fs.outputJson( `${config.tribes}/${config.mayorId}/nationchains/nodes/${u}`, data );
					} )
				} )
				.catch( err => {
					//Not available
					data.negatifupdate += 1;
					data.lasttimeupdate = Date.now();
					fs.outputJson( `${config.tribes}/${config.mayorId}/nationchains/nodes/${u}`, data );
				} );
		}
	} );
};


module.exports = Nationchains;
