const glob = require( 'glob' );
const path = require( 'path' );
const fs = require( 'fs-extra' );
// Check if package is installed or not to pickup the right config file
const config = require( '../tribes/townconf.js' );

const Referentials = {};
/*
Manage Referential object data

each object is compose of a list of fields
each fields have it owns structur and check
those common rules allow to be used to manage:
- forms (creation to collect data)
- data check
- data access rights
common referential data stored in /data/shared/referential/

*/
Referentials.clientconf = ( xworkOn, listkey ) => {
	/*
	Retourne les info d'un clientconf.json sur une liste de [cle]
	*/
	let conf = {};
	let dataconf = {};
	logger.info( `${config.tribes}/${xworkOn}/clientconf.json` )
	try {
		conf = fs.readJsonSync( `${config.tribes}/${xworkOn}/clientconf.json` );
		// remove information notrelevant for
    [ 'emailFrom', 'emailClient', 'emailCc', 'commentkey', 'clezoomprivate', 'stripekeyprivate', 'genericpsw' ].forEach( c => {
			delete conf[ c ];
		} );
		listkey.forEach( k => dataconf[ k ] = conf[ k ] )
		logger.info( 'dataconf', dataconf )
	} catch ( err ) {
		logger.info( 'Attention demande sur clienId inconnu ' + xworkOn );
	}
	return {
		status: 200,
		payload: {
			data: dataconf
		}
	};
};
Referentials.clientconfglob = () => ( {
	status: 200,
	payload: {
		data: fs.readJsonSync( `${config.tmp}/clientconfglob.json` )
	}
} );

Referentials.inittribeid = () => {
	logger.info( "Clientconf list for this server", `${config.tribes}/**/clientconf.json` );
	const TribesGlobalConfig = glob.sync( `${config.tribes}/**/clientconf.json` )
		.map( f => fs.readJsonSync( f ) );
	// store global conf for sharing to other api
	fs.outputJsonSync( `${config.tmp}/clientconfglob.json`, TribesGlobalConfig, {
		spaces: 2
	} );
	return { status: 200, payload: { moreinfo: TribesGlobalConfig } }
}


Referentials.generetribeids = () => {
	const tribeids = [];
	fs.readJsonSync( `${config.tmp}/clientconfglob.json` )
		.forEach( c => {
			if( !tribeids.includes( c.tribeid ) ) tribeids.push( c.tribeid );
		} );
	fs.outputJsonSync( `${config.tmp}/tribeids.json`, tribeids );
	logger.info( `update ${config.tribes}/tribeids` );
	return tribeids;
}
Referentials.genereallowedDOM = () => {
	const confglob = fs.readJsonSync( `${config.tmp}/clientconfglob.json` );
	let allDom = [];
	confglob.forEach( c => {
		c.allowedDOMs.forEach( d => {
			if( !allDom.includes( d ) ) allDom = allDom.concat( d );
		} )
	} );
	return allDom;
};


Referentials.getref = ( source, ref, xworkOn, xlang, singlelang = true ) => {
	let referent = {};
	let src = `${config.tribes}/${xworkOn}/referentials/${xlang}/${source}/${ref}.json`;
	if( !singlelang ) {
		//request full referential to manage
		src = `${config.tribes}/${xworkOn}/referentials/dataManagement/${source}/${ref}.json`
	}
	logger.info( src )
	try {
		referent = fs.readJsonSync( src );
	} catch ( err ) {
		logger.info( `Attention demande de referentiel inexistant pour ${src} ` );
	}
	return {
		status: 200,
		payload: {
			data: referent
		}
	};
};
Referentials.putref = ( source, name, xworkOn, data ) => {
	/*
	We get a referential, we have 3 kinds of sources:
	 * data = [{uuid,desc:{fr:,en,},desclong:{fr:,en:}, other field}]
	        only desc and desclong have a translation
	 * json = {"fr":{},"en":{}, ...} are full complex object in language
	 * object = [{uuid,desc:{fr,en},desclong:{fr,en}},tpl,}]
	Difference between data and object is that object defines rule to manage an object, and how to create a forms to get data each data is saved in one folder object/uuid.json and have to respect the corresponding object referentials definition.

	*/
	logger.info( data )
	// Create a backup of the day hour if exist
	const file = `${config.tribes}/${xworkOn}/referentials/dataManagement/${source}/${name}.json`

	if( fs.existsSync( file ) ) {
		//backup change done per hour
		const origin = fs.readJsonSync( file, 'utf-8' )
		fs.outputJsonSync( `${config.tribes}/${xworkOn}/referentials/dataManagementBackup/${source}/${name}${moment().format('YYYYMMDDHHmm')}.json`, origin, { spaces: 2 } )
	} else {
		logger.info( `Referential ${name}.json does not exist this created it` )
	}
	logger.info( 'ref backup before update', name );
	fs.outputJsonSync( file, data, { spaces: 2 } );
	// update/create new referential and new version
	return Referentials.update( xworkOn, source, name );
};
Referentials.updatefull = ( tribeid ) => {
	// source json are only per lg so no full update for json
	let err = "";
	 [ 'object', 'data' ].forEach( o => {
		glob.sync( `${config.tribes}/${tribeid}/referentials/dataManagement/${o}/*.json` )
			.forEach( f => {
				if( finipaspar_lg ) {
					const res = Referentials.update( tribeid, o, path.basename( f, '.json' ) );
					if( res.status != 200 ) {
						err += `Error on ${o}/${path.basename(f)}`
					}
				}
			} )
	} );
	if( err != "" ) {
		return { status: 500, payload: { info: [ 'Errupdateref' ], model: "Referentials", moreinfo: err } }
	}
	return { status: 200, payload: { info: [ 'Success' ], model: "Referentials" } }
};

Referentials.update = ( tribeid, source, name ) => {
	/*
	Replace for each language the referential name for a tribeid
	After each update the version number is incremented by 1 in clientconf.json
	*/
	if( !fs.existsSync( `${config.tribes}/${tribeid}/referentials/${source}/${name}.json` ) ) {
		return { status: 500, payload: { info: [ "unknownRef" ], model: "Referentials", moreinfo: `file does not exist ${config.tribes}/${tribeid}/referentials/${source}/${name}.json` } }
	};

	const clientconf = fs.readJsonSync( `${config.tribes}/${tribeid}/clientconf.json` );
	if( !clientconf.langueReferential ) {
		return { status: 500, payload: { info: [ "missingConf" ], model: "Referentials", moreinfo: ` ${config.tribes}/${tribeid}/clientconf.json does not contain langueReferential array` } }
	}
	const ref = fs.readJsonSync( `${config.tribes}/${tribeid}/referentials/${source}/${name}.json` );

	clientconf.langueReferential.forEach( lg => {
		/*if( !fs.existsSync( `${config.tribes}/${tribeid}/referentials/${lg}` ) ) {
					[ '', '/data', '/json', '/object' ].forEach( p => {
				fs.mkdirSync( `${config.tribes}/${tribeid}/referentials/${lg}${p}` );
			} )
		}
		*/
		//manage translation
		let refnew = [];
		if( source == 'json' ) {
			refnew = ref[ lg ]
		} else {
			refnew = [];
			ref.forEach( d => {
				if( d.desc ) d.desc = d.desc[ lg ];
				if( d.desclong ) d.desclong = d.desclong[ lg ];
				if( d.info ) d.info = d.info[ lg ];
				if( d.placeholder ) d.placeholder = d.placeholder[ lg ];
				refnew.push( d )
			} )
		}
		//save new ref in language
		logger.info( "testtttt", refnew )
		logger.info( `${config.tribes}/${tribeid}/referentials/${source}/${name}_${lg}.json` )
		fs.outputJsonSync( `${config.tribes}/${tribeid}/referentials/${source}/${name}_${lg}.json`, refnew, {
			spaces: 2
		} );
	} );
	//upgrade version number
	if( !clientconf.referentials[ source ][ name ] ) clientconf.referentials[ source ][ name ] = { version: 0 };
	clientconf.referentials[ source ][ name ].version += 1;
	return {
		status: 200,
		payload: {
			info: [ 'successUpdate' ],
			model: "Referentials",
			moreinfo: `${name} updated`
		}
	}
};
//logger.info( Referentials.update( 'apixtribe', "object", "user" ) )

Referentials.genereobjet = ( tribeid, destination, tplmustache, objet, filtre ) => {
	/* @TODO
	 Genere des objets d'agregat
	 @tribeid = data/tribee/ identifiant client
	 @destinations = [] of destination
	 @tplmustache = fichier mustache de mise en page
	 @objet =   nom d'objet contact, companies, items, users
	 @filtre = fonction a executer
	*/
}

module.exports = Referentials;
