const express = require( 'express' );
const fs = require( 'fs-extra' );
const path = require( 'path' );
const config = require( '../tribes/townconf.js' );

// Classes
const Tribes = require( '../models/Tribes.js' );
// Middlewares
const checkHeaders = require( '../middlewares/checkHeaders' );
const isAuthenticated = require( '../middlewares/isAuthenticated' );
const hasAccessrighton = require( '../middlewares/hasAccessrighton' );
const router = express.Router();


router.get( '/clientconf/:tribeid', checkHeaders, isAuthenticated, ( req, res ) => {
	/*
	get a clientconf.json for a tribeid depending of user accessright
	if tribeid == all and user is admin of apixtribe => get /tmp/clientconfglob.json
	req.session.header.accessrights, req.session.header.apixpaganid
	*/
	logger.info( `Tribes/clientconf for tribeid:${req.params.tribeid}` )
	if( req.params.tribeid == "all" && req.session.header.accessrights.data.apixtribe && req.session.header.accessrights.data.apixtribe.tribeid && req.session.header.accessrights.data.apixtribe.tribeid.includes( 'R' ) ) {
		res.status( 200 )
			.send( { moreinfo: fs.readJsonSync( `${config.tmp}/clientconfglob.json`, 'utf-8' ) } );
		return;
	}
	if( req.session.header.accessrights.data[ req.params.tribeid ] &&
		req.session.header.accessrights.data[ req.params.tribeid ].tribeid &&
		req.session.header.accessrights.data[ req.params.tribeid ].tribeid.includes( 'R' ) &&
		fs.existsSync( `${config.tribes}/${req.params.tribeid}/clientconf.json` ) ) {
		//		const conftribeid = { moreinfo: {} }
		//		conftribeid.moreinfo[ req.params.tribeid ] = fs.readJsonSync( `${config.tribes}/${req.params.tribeid}/clientconf.json`, 'utf-8' );
		res.status( 200 )
			.send( { moreinfo: [ fs.readJsonSync( `${config.tribes}/${req.params.tribeid}/clientconf.json`, 'utf-8' ) ] } );
		return;
	}
	// if not authorized or dos not exist return empty
	// no specific message is send for security reason (check only log)
	res.status( 403 )
		.send( { info: [ 'forbidenAccess' ], models: 'Tribes' } )
		.end();
} )
router.put( '/', checkHeaders, isAuthenticated, ( req, res ) => {
	logger.info( 'Create a new tribeid, with a useradmin' )
	logger.info( ' send data = clientconf.json with all parameter.' )
	// !!!!! check for security any ; \n or so because data can be used into shell
	const add = Tribes.create( req.body );
	res.status( add.status )
		.send( add.payload )
} )
router.delete( '/archivetribeid/:tribeid', checkHeaders, isAuthenticated, ( req, res ) => {
	logger.info( "request archive tribeid" )
	const archive = Tribes.archive( req.params.tribeid );
	res.status( archive.status )
		.send( archive.payload )
} );
router.post( '/spaceweb', checkHeaders, isAuthenticated, ( req, res ) => {
	// !!!!! check for security any ; \n or so because data can be used into shell
	logger.info( 'Create a new webapp for xworkon ' )
	req.body.tribeid = req.session.header.xworkon;
	const add = Tribes.addspaceweb( req.body )
	res.status( add.status )
		.send( add.payload )
} )
router.get( '/spaceweb/components/:tribeid/:website/:key', checkHeaders, ( req, res ) => {
	// check if key is valid before continue
	// exemple: get Tribes/spaceweb/components/ndda/mesa/123?rep=appmesatable/appsimpletable.mustache
	const file = `${config.tribes}/${req.params.tribeid}/spacedev/${req.params.website}/src/ctatic/components/${req.query.path}`
	logger.info( `Request components file from ${file}` )
	if( fs.existsSync( file ) ) {
		res.sendFile( file );
	} else {
		res.send( `console.error("Missing components file in ${req.params.tribeid}/spacedev/${req.params.website}/src/ctatic/components/${req.query.path}");` );
	}
} )
router.get( '/plugins/:tribeid/:pluginname/:key/:filename', ( req, res ) => {
	// No accessright possible cause it is load on the fly
	// @todo Check key to authorize access to the plugin (key comme from user ACCESSRIGHTS[tribeid plugin owner:pluginname]).key
	// return a file into /:tribeid owner of plugin/plugins/:pluginname/components/:filename
	// if not exist or invalid key then return console.error
	const file = `${config.tribes}/${req.params.tribeid}/plugins/${req.params.pluginname}/components/${req.params.filename}`
	logger.info( 'Tribes/plugins/ ', file )
	if( fs.existsSync( file ) ) {
		res.sendFile( file );
	} else {
		res.send( `console.error("Missing plugin file in ${req.params.tribeid}/plugins/${req.params.pluginname}/components/${req.params.filename}");` );
	}
} );

router.get( '/dirls', checkHeaders, isAuthenticated, ( req, res ) => {
	// url /Tribes/dirls?rep=referentials/dataManagement
	// request information about a req.query.rep from header xworkon/
	// return
	// {file:[{}],dir:[{}]}
	// @todo check if isAuthorized and exist

	logger.info( 'request dirls', `${config.tribes}/${req.session.header.xworkon}/${req.query.rep}` );
	if( !fs.existsSync( `${config.tribes}/${req.session.header.xworkon}/${req.query.rep}` ) ) {
		res.status( 404 )
			.send( { 'info': [ 'dirnotexist' ], model: 'Tribes' } );
	}
	const info = Tribes.dirls( req.session.header.xworkon, req.query.rep );
	logger.info( info )
	res.status( info.status )
		.send( info.payload );
} )
router.delete( '/ls', checkHeaders, isAuthenticated, ( req, res ) => {
	// check Accessright with D or O on each
	// url /Tribes/ls
	// req.body.files=[listfiles file to delete ]
	const authfiles = Tribes.checkaccessfiles( req.body, 'D', req.session.header.accessrights, req.session.header.apixpaganid );
	authfiles.ok.forEach( f => { fs.remove( `${config.tribes}/${f}` ); } )
	res.status( 200 )
		.send( { 'info': [ 'fileauthdeleted' ], models: 'Tribes', moreinfo: authfiles } )
} );
router.put( '/sendjson', checkHeaders, isAuthenticated, ( req, res ) => {
	//req.body = {object:spacedev, path:website/src/data/tpldataname_lg.json, data:{...}}
	//logger.info( req.body )
	const dest = `${config.tribes}/${req.session.header.xworkon}/${req.body.object}/${req.body.path}`;
	logger.info( `Send json to saved to ${dest}` );
	if( !( req.body.object && fs.existsSync( `${config.tribes}/${req.session.header.xworkon}/${req.body.object}` ) ) ) {
		res.status( '404' )
			.send( { info: [ 'objectmissiong' ], models: 'Tribes', moreinfo: `object: ${req.body.object} does not exist req.body must {object, data, path} into data ${req.session.header.xworkon}/${req.body.object}` } )
	} else {
		if( fs.existsSync( `${config.tribes}/${req.session.header.xworkon}/${req.body.object}/${req.body.path}` ) ) {
			// exist so can be update check accessright update on this
			hasAccessrighton( req.body.object, "U" );
		} else {
			hasAccessrighton( req.body.object, "C" );
		}
		fs.outputJsonSync( dest, req.body.data );
		res.status( 200 )
			.send( { info: [ 'filesaved' ], models: 'Tribes' } )
	}
} );
router.post( '/downloadls', checkHeaders, isAuthenticated, ( req, res ) => {
	// midlleware hasAccessrighton.js is not apply here only to access/update/create information inside an object
	// to get file a user need accessrights to data: object: R or to Own it
	// or if exist a .info.json into folder get shared as R in uuid

	//req.body contain list of path file or folder if only 1 file then download it, otherwise zip list and send zip file

	const authfiles = Tribes.checkaccessfiles( req.body.files, 'R', req.session.header.accessrights, req.session.header.xpaganid );
	if( authfiles.ok.length == 1 ) {
		// bidouille en attendnat de faire un .zip binaire propre
		if( !authfiles.ok[ 0 ].includes( '.xml' ) ) {
			res.status( 200 )
				.download( `${config.tribes}/${authfiles.ok[0]}`, authfiles.ok[ 0 ] );
		} else {
			fs.copySync( `${config.tribes}/${authfiles.ok[0]}`, `${config.tribes}/${config.mayorId}/www/app/webapp/static/tmp/${authfiles.ok[ 0 ]}` )
		}
	} else if( authfiles.ok.length > 1 ) {
		// on zip et on envoie
		//res.status( 200 )
		//	.download( `${config.tribes}/${authfiles.ok[0]}`, authfiles.ok[ 0 ])
		res.status( 200 )
			.attachment( `${config.tribes}/${authfiles.ok[0]}` );

	} else {
		req.body.filepon
		res.status( 403 )
			.send( 'Forbidden access' )
	}
} );
router.post( '/upfilepond', checkHeaders, isAuthenticated, ( req, res ) => {
	logger.info( 'post /Tribes/uploadfilepond' );
	// Store file and return a unique id to save button
	// that provide folder where to store it
	const formidable = require( 'formidable' );
	const form = formidable( { multiples: false } );
	form.parse( req, ( err, fields, files ) => {
		if( err ) { next( err ); return; }
		//logger.info( 'fields',fields);
		// fileMetadaObject send
		let context = JSON.parse( fields.filepond );
		let idfile = files.filepond.path;
		let name = files.filepond.name;
		let subfolder = context.subfolder;
		name = name.replace( /[ ,'"’]/g, "_" );
		//logger.info( 'files.filepond:', files.filepond );
		logger.info( idfile, `${config.tribes}/${req.session.header.xworkon}/www/${subfolder}/${name}` )
		// On le supprime s'il existe deja
		fs.removeSync( `${config.tribes}/${req.session.header.xworkon}/www/${subfolder}/${name}` );
		// mv tmp
		fs.moveSync( idfile, `${config.tribes}/${req.session.header.xworkon}/www/${subfolder}/${name}` );
		//res.status(200).send({models:"Tribes",info:["Savedsuccess"],moreinfo:{id:file.filepond.path}})
		//return for filepond
		res.writeHead( 200, { 'Content-Type': 'text/plain' } );
		res.end( idfile );
	} )
} );
router.delete( '/file', checkHeaders, isAuthenticated, ( req, res ) => {
	//src = objectfolder with accessright/...
	//hasAccessrighton( "www", "D" ),
	if( !req.query.src ) {
		res.status( 404 )
			.send( { info: [ 'deleteerror' ], models: "Tribes", moreinfo: "your del req need a src" } )
		return;
	};
	hasAccessrighton( req.query.src.split( '/' )[ 0 ], "D" );
	logger.info( 'Remove file', `${config.tribes}/${req.session.header.xworkon}/${req.query.src}` )
	logger.info( req.body )
	fs.removeSync( `${config.tribes}/${req.session.header.xworkon}/${req.query.src}` );
	res.status( 200 )
		.send( { info: [ 'Successfullremove' ], models: "Tribes" } )
} );
router.post( '/uploadfile', checkHeaders, isAuthenticated, ( req, res ) => {
	logger.info( 'upload a file  ' )
	/* Authentification is needed to get a TOKEN
		curl -X POST -H "xtribe: apixtribe" -H "xworkon: pvmsaveurs" -H "xlang: fr" -H "xpaganid: 1" -H "xauth: 1" -H "xapp: pvmsaveurs:pvmsaveurs" -H "Content-Type: application/json" -d '{"LOGIN":"adminapixtribe","PASSWORD":"Trze3aze!"}' http://pvmsaveurs.pvmsaveurs.fr/app/users/login
		 if exist replace xpaganidTOKEN with payload.TOKEN value

		curl -H "xtribe: pvmsaveurs" -H "xworkon: pvmsaveurs" -H "xlang: fr" -H "xpaganid: adminapixtribe" -H "xauth: xpressuuisToken" -H "xapp: pvmsaveurs:pvmsaveurs" -F 'data=@filename.xx' http://pvmsaveurs.pvmsaveurs.fr/app/Tribes/uploadfile
	 */
	const formidable = require( 'formidable' );
	const form = formidable( { multiples: false } );
	form.parse( req, function ( err, fields, files ) {
		//logger.info( files.data )
		var oldPath = files.data.path;
		var newPath = `${config.tribes}/${req.session.header.xworkon}/${clientconf.uploadzip[files.data.name].dest}`;
		logger.info( 'oldPath', oldPath )
		logger.info( 'newPath', newPath )
		var rawData = fs.readFileSync( oldPath )
		fs.outputFile( newPath, rawData, function ( err ) {
			if( err ) {
				logger.info( err );
				return res.status( 405 )
					.send( { info: [ 'savederror' ], models: "Tribes", moreinfo: "your file was not able to be saved into the server" } )
			} else {
				return res.status( 200 )
					.send( {
						info: [ "successfullsent" ],
						models: "Tribes"
					} );
			}
		} )
	} );
} );
router.post( '/uploadzip', checkHeaders, ( req, res ) => {
	logger.info( 'uploadzip a file  ' )

	/* no authentification to upload a zip filename into /tribes/${xworkon}/${clientconf.uploadzip[filename].dest}
	unzip it using the password ${clientconf.uploadzip[filename].psw
	if no error then run the callback ${clientconf.uploadzip[filename].callback
				 but a password to unzip
				 in clientconf.json need to be set
				 "uploadzip": {
		 	    "articlesTribespvm.zip": {
		 	      "comment": "unzip with overwrite if same name",
		 	      "psw": "azPI1209qtrse",
		 	      "dest": "importexport/tmp",
		 	      "unzipoption": "-aoa",
		 	      "callback": "importexport/integrationitem.js"
		 	    }
		 	  },
          Example:
					cd where zip file is stored
					curl -H "xtribe: pvmsaveurs" -H "xworkon: pvmsaveurs" -H "xlang: fr" -H "xpaganid: adminapixtribe" -H "xauth: 1" -H "xapp: pvmsaveurs:pvmsaveurs" -F 'data=@articlesTribespvm.zip' http://pvmsaveurs.pvmsaveurs.fr/app/Tribes/uploadzip

				 */
	const clientconf = fs.readJSONSync( `${config.tribes}/${req.session.header.xworkon}/clientconf.json` )
	if( !clientconf.uploadzip ) {
		return res.status( '404' )
			.send( { info: [ "missconf" ], models: "Tribes", moreinfo: `no uploadzip in clientconf for ${req.session.header.xworkon} please contact apixtribe admin ` } );
	};
	const uploadzip = clientconf.uploadzip;
	const formidable = require( 'formidable' );
	const form = formidable( { multiples: false } );
	form.parse( req, function ( err, fields, files ) {
		//logger.info( files.data )
		var oldPath = files.data.path;
		if( !Object.keys( clientconf.uploadzip )
			.includes( files.data.name ) ) {
			return res.status( 403 )
				.send( { info: [ "notAllowed" ], models: "Tribes", moreinfo: `file ${files.data.name} not allowed to be upload` } )
		} else {
			logger.info( "context:", clientconf.uploadzip[ files.data.name ] )
			var newPath = `${config.tribes}/${req.session.header.xworkon}/${clientconf.uploadzip[files.data.name].dest}`;
			//logger.info( 'oldPath', oldPath )
			//logger.info( 'newPath', `${newPath}/${files.data.name}` )
			fs.moveSync( oldPath, `${newPath}/${files.data.name}`, { overwrite: true } );
			const cp = require( 'child_process' );
			//logger.info( `7z e -p${clientconf.uploadzip[ files.data.name ].psw} ${newPath}/${files.data.name}` );
			logger.info( '7z', [ 'e', `-p${clientconf.uploadzip[ files.data.name ].psw}`, `${newPath}/${files.data.name}`, `-o${config.tribes}/${req.session.header.xworkon}/${clientconf.uploadzip[ files.data.name ].dest}`, clientconf.uploadzip[ files.data.name ].unzipoption ] );
			var newFiles = cp.spawnSync( '7z', [ 'e', `-p${clientconf.uploadzip[ files.data.name ].psw}`, `${newPath}/${files.data.name}`, `-o${config.tribes}/${req.session.header.xworkon}/${clientconf.uploadzip[ files.data.name ].dest}`, clientconf.uploadzip[ files.data.name ].unzipoption ] );
			logger.info( newFiles.output.toString() )
			if( newFiles.output.toString()
				.includes( 'Everything is Ok' ) ) {
				if( clientconf.uploadzip[ files.data.name ].callback ) {
					const integ = require( `${config.tribes}/${req.session.header.xworkon}/${clientconf.uploadzip[files.data.name].callback}` )
						.run();
					logger.info( 'integration', integ )
					return res.status( integ.status )
						.send( integ.payload );
				} else {
					return res.status( 200 )
						.send( {
							info: [ "successfullsent" ],
							models: "Tribes"
						} );
				}
			} else {
				return res.status( 400 )
					.send( {
						info: [ "zipfileerror" ],
						models: "Tribes",
						moreinfo: newFiles.output.toString()
					} )
			}
		}
	} )
} );

router.post( '/upload', checkHeaders, isAuthenticated, ( req, res ) => {
	1 //  ACHANGER VIA usage sendjson
	// url /Tribes/upload?save=tmp&rep=referentials/dataManagement
	// if save=tmp then store in a tmp file
	// if save=ok then mv the tmp file to the folder
	// midlleware hasAccessrighton.js is not apply here only to access/update/create information inside an object
	// to upload a file a user need accessrights to data: object: C or to Own it
	// or if dir.file exist a .info.json into folder get shared as C in uuid accessright
	/*
 to add in front
 <form action="/upload" method="POST"  enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="submit" value="upload"/>
</form>
 */
	logger.info( 'Envoie image' )
	logger.info( 'body', req.body );
	logger.info( 'params', req.params );
	//const authfolder = Tribes.checkaccessfiles( req.params.rep, 'C', req.session.header.accessrights, req.session.header.xpaganid );
	// cheack autorisation to create or replace a file for this accessrights user
	const authfolder = { ok: "tt" }
	if( authfolder.ok ) {
		if( req.params.save == 'file' ) {
			if( fs.existsSync( req.body.filepond ) ) {
				fs.mv( req.body.filepond, req.params.rep );
			}
		};
		// voir si c'est toujours pertinent car upload est géré par filepond pour les image
		if( req.params.save == 'upload' ) {
			const form = formidable( { multiples: false } );
			form.parse( req, ( err, fields, files ) => {
				if( err ) { next( err ); return; }
				let thefile = files.filebond.path;
				fs.outputFileSync()
				logger.info( 'thefile:' + thefile );
				res.writeHead( 200, { 'Content-Type': 'text/plain' } );
				res.end( theFile );
			} )
		}
	} else {
		res.status( 403 )
			.send( 'forbiden access' );
	}
} );
/*
Manage tribeid into /data/tribee/tribeid
client space dedicated

@Todo
clientconfglob copy cut from Referentials.clientconfglob
clientconf.json copy cut from Referentials.clientconf
list of tribeid copy cut from Referentials.
Add a tribeid
update clientconf


*/



module.exports = router;
