// vi: ts=4 sw=4 noet:
/*
==================================================================================
    Copyright (c) 2020 AT&T Intellectual Property.
    Copyright (c) 2020 Nokia

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================================
*/

/*
    Mnemonic:	config.cpp
    Abstract:	Support for reading config json.

				The config structure allows simplified parsing of the json and
				easy access to the things we belive all xAPPs will use (port
				digging form the named "interface" and control settings). This
				also supports the watching on the file and driving the user
				callback when the config file appears to have changed (write
				close on the file).

				Accessing information from the json is serialised (mutex) as
				with the random nature of file updates, we must ensure that
				we don't change the json as we're trying to read from it. Locking
				should be transparent to the user xAPP.

    Date:       27 July 2020
    Author:     E. Scott Daniels
*/

#include <errno.h>
#include <poll.h>
#include <stdlib.h>
#include <sys/inotify.h>
#include <unistd.h>
#include <string.h>

#include <iostream>
#include <sstream>
#include <fstream>
#include <thread>
#include <memory>

#include "jhash.hpp"
#include "config.hpp"
#include "config_cb.hpp"

namespace xapp {


// ----- private things --------
/*
	Notification listener. This function is started in a thread and listens for
	changes to the config file. When it sees an interesting change (write close)
	to the file, then it will read the new set of json, parse it, and drive the
	user callback.

	We must watch the directory containing the file as if the file is edited and
	replaced it's likely saved with a different referencing inode. We'd see the
	first change, but not any subsequent changes as the inotify is based on inodes
	and not directory entries.
*/
void xapp::Config::Listener( ) {
	struct inotify_event*	ie;		// event that popped
	int ifd;						// the inotify file des
	int	wfd;						// the watched file des
	int	n;
	char	rbuf[4096];				// large read buffer as the event is var len
	char*	dname;					// directory name
	char*	bname;					// basename
	char*	tok;

	ifd = inotify_init1( 0 );		// initialise watcher setting blocking read (no option)
	if( ifd < 0 ) {
		fprintf( stderr, "<XFCPP> ### ERR ### unable to initialise file watch %s\n", strerror( errno ) );
		return;
	}

	dname = strdup( fname.c_str() );					// defrock the file name into dir and basename
	if( (tok = strrchr( dname, '/' )) != NULL ) {
		*tok = 0;
		bname = strdup( tok+1 );
	} else {
		free( dname );
		dname = strdup( "." );
		bname = strdup( fname.c_str() );
	}

	wfd = inotify_add_watch( ifd, (char *) dname, IN_MOVED_TO | IN_CLOSE_WRITE );		// we only care about close write changes

	if( wfd < 0 ) {
		fprintf( stderr, "<XFCPP> ### ERR ### unable to add watch on config file %s: %s\n", fname.c_str(), strerror( errno ) );
		return;
	}

	while( true ) {
		n = read( ifd, rbuf, sizeof( rbuf ) );				// read the event
		if( n < 0  ) {
			if( errno == EAGAIN ) {
				continue;
			} else {
				fprintf( stderr, "<XFCPP ### CRIT ### config listener read err: %s\n", strerror( errno ) );
				return;
			}
		}

		ie = (inotify_event *) rbuf;
		if( ie->len > 0 && strcmp( bname, ie->name ) == 0  ) {
			// TODO: lock
			auto njh = jparse( fname );							// reparse the file
			// TODO: unlock

			if( njh != NULL && cb != NULL ) {				// good parse, save and drive user callback
				jh = njh;
				cb->Drive_cb( *this, user_cb_data );
			}
		}
	}
}


/*
	Read a file containing json and parse into a framework Jhash.

	Using C i/o will speed this up, but I can't imagine that we need
	speed reading the config file once in a while.
	The file read comes from a stack overflow example:
		stackoverflow.com/questions/2912520/read-file-contents-into-a-string-in-c
*/
std::shared_ptr<xapp::Jhash> xapp::Config::jparse( std::string ufname ) {
	fname = ufname;

	std::ifstream ifs( fname );
	std::string st( (std::istreambuf_iterator<char>( ifs ) ), (std::istreambuf_iterator<char>() ) );

	auto new_jh = std::shared_ptr<xapp::Jhash>( new xapp::Jhash( st.c_str() ) );
	return  new_jh->Parse_errors() ? NULL : new_jh;
}

/*
	Read the configuration file from what we find as the filename in the environment (assumed
	to be referenced by $XAPP_DESCRIPTOR_PATH/config-file.json. If the env var is not
	defined we assume ./.  The data is then parsed with the assumption that it's json.

	The actual meaning of the environment variable is confusing. The name is "path" which
	should mean that this is the directory in which the config file lives, but the examples
	elsewhere suggest that this is a filename (either fully qualified or relative). For now
	we will assume that it's a file name, though we could add some intelligence to determine
	if it's a directory name or not if it comes to it.
*/
std::shared_ptr<xapp::Jhash> xapp::Config::jparse( ) {
	char*	data;

	if( (data = getenv( (char *) "XAPP_DESCRIPTOR_PATH" )) == NULL ) {
		data =  (char *) "./config-file.json";
	}

	return jparse( std::string( data ) );
}

// --------------------- construction, destruction -------------------------------------------

/*
	By default expect to find XAPP_DESCRIPTOR_PATH in the environment and assume that it
	is the directory name where we can find config-file.json. The build process will
	read and parse the json allowing the user xAPP to invoke the supplied  "obvious"
	functions to retrieve data.  If there is something in an xAPP's config that isn't
	standard, it can get the raw Jhash object and go at it directly. The idea is that
	the common things should be fairly painless to extract from the json goop.
*/
xapp::Config::Config() :
	jh( jparse() ),
	listener( NULL )
{ /* empty body */ }

/*
	Similar, except that it allows the xAPP to supply the filename (testing?)
*/
xapp::Config::Config( std::string fname) :
	jh( jparse( fname ) ),
	listener( NULL )
{ /* empty body */ }


/*
	Read and return the raw file blob as a single string. User can parse, or do
	whatever they need (allows non-json things if necessary).
*/
std::string xapp::Config::Get_contents( ) {
	std::string rv = "";

	if( ! fname.empty() ) {
		std::ifstream ifs( fname );
		std::string st( (std::istreambuf_iterator<char>( ifs ) ), (std::istreambuf_iterator<char>() ) );
		rv = st;
	}

	return rv;
}

// ----- convience function for things we think an xAPP will likely need to pull from the config


/*
	Suss out the port for the named "interface". The interface is likely the application
	name.
*/
std::string xapp::Config::Get_port( std::string name ) {
	int i;
	int	nele = 0;
	double value;
	std::string rv = "";		// result value
	std::string pname;			// element port name in the json

	if( jh == NULL ) {
		return rv;
	}

	jh->Unset_blob();
	if( jh->Set_blob( (char *) "messaging" ) ) {
		nele = jh->Array_len( (char *) "ports" );
		for( i = 0; i < nele; i++ ) {
			if( jh->Set_blob_ele( (char *) "ports", i ) ) {
				pname = jh->String( (char *) "name" );
				if( pname.compare( name ) == 0 ) {				// this element matches the name passed in
					value = jh->Value( (char *) "port" );
					rv = std::to_string( (int) value );
					jh->Unset_blob( );							// leave hash in a known state
					return rv;
				}
			}

			jh->Unset_blob( );								// Jhash requires bump to root, and array reselct to move to next ele
			jh->Set_blob( (char *) "messaging" );
		}
	}

	jh->Unset_blob();
	return rv;
}

/*
	Suss out the named string from the controls object. If the resulting value is
	missing or "", then the default is returned.
*/
std::string xapp::Config::Get_control_str( std::string name, std::string defval ) {
	std::string value;
	std::string rv;				// result value

	rv = defval;
	if( jh == NULL ) {
		return rv;
	}

	jh->Unset_blob();
	if( jh->Set_blob( (char *) "controls" ) ) {
		if( jh->Exists( name.c_str() ) )  {
			value = jh->String( name.c_str() );
			if( value.compare( "" ) != 0 ) {
				rv = value;
			}
		}
	}

	jh->Unset_blob();
	return rv;
}

/*
	Convenience funciton without default. "" returned if not found.
	No default value; returns "" if not set.
*/
std::string xapp::Config::Get_control_str( std::string name ) {
	return Get_control_str( name, "" );
}

/*
	Suss out the named field from the controls object with the assumption that it is a boolean.
	If the resulting value is missing then the defval is used.
*/
bool xapp::Config::Get_control_bool( std::string name, bool defval ) {
	bool value;
	bool rv;				// result value

	rv = defval;
	if( jh == NULL ) {
		return rv;
	}

	jh->Unset_blob();
	if( jh->Set_blob( (char *) "controls" ) ) {
		if( jh->Exists( name.c_str() ) )  {
			rv = jh->Bool( name.c_str() );
		}
	}

	jh->Unset_blob();
	return rv;
}


/*
	Convenience function without default.
*/
bool xapp::Config::Get_control_bool( std::string name ) {
	return Get_control_bool( name, false );
}


/*
	Suss out the named field from the controls object with the assumption that it is a value (float/int).
	If the resulting value is missing then the defval is used.
*/
double xapp::Config::Get_control_value( std::string name, double defval ) {
	double value;

	auto rv = defval;				// return value; set to default
	if( jh == NULL ) {
		return rv;
	}

	jh->Unset_blob();
	if( jh->Set_blob( (char *) "controls" ) ) {
		if( jh->Exists( name.c_str() ) )  {
			rv = jh->Value( name.c_str() );
		}
	}

	jh->Unset_blob();
	return rv;
}


/*
	Convenience function. If value is undefined, then 0 is returned.
*/
double xapp::Config::Get_control_value( std::string name ) {
	return Get_control_value( name, 0.0 );
}


// ---- notification support ---------------------------------------------------------------


/*
	Accept the user's notification function, and data that it needs (pointer to
	something unknown), and stash that as a callback.

	The fact that the user xAPP registers a callback also triggers the creation
	of a thread to listen for changes on the config file.
*/
void xapp::Config::Set_callback( notify_callback usr_func, void* usr_data ) {
	cb = std::unique_ptr<Config_cb>( new Config_cb( usr_func, usr_data ) );
	user_cb_data = usr_data;

	if( listener == NULL ) {				// start thread if needed
		listener = new std::thread( &xapp::Config::Listener, this );
	}
}

} // namespace
