"""The module describes the ``core`` job metrics plugin."""
import logging
import time

from ..instrumenters import InstrumentPlugin
from ...metrics import formatting

log = logging.getLogger( __name__ )

GALAXY_SLOTS_KEY = "galaxy_slots"
START_EPOCH_KEY = "start_epoch"
END_EPOCH_KEY = "end_epoch"
RUNTIME_SECONDS_KEY = "runtime_seconds"


class CorePluginFormatter( formatting.JobMetricFormatter ):

    def format( self, key, value ):
        value = int( value )
        if key == GALAXY_SLOTS_KEY:
            return ( "Cores Allocated", "%d" % value )
        elif key == RUNTIME_SECONDS_KEY:
            return ( "Job Runtime (Wall Clock)", formatting.seconds_to_str( value ) )
        else:
            # TODO: Use localized version of this from galaxy.ini
            title = "Job Start Time" if key == START_EPOCH_KEY else "Job End Time"
            return (title, time.strftime( '%Y-%m-%d %H:%M:%S', time.localtime( value ) ) )


class CorePlugin( InstrumentPlugin ):
    """ Simple plugin that collects data without external dependencies. In
    particular it currently collects value set for Galaxy slots.
    """
    plugin_type = "core"
    formatter = CorePluginFormatter()

    def __init__( self, **kwargs ):
        pass

    def pre_execute_instrument( self, job_directory ):
        commands = []
        commands.append( self.__record_galaxy_slots_command( job_directory ) )
        commands.append( self.__record_seconds_since_epoch_to_file( job_directory, "start" ) )
        return commands

    def post_execute_instrument( self, job_directory ):
        commands = []
        commands.append( self.__record_seconds_since_epoch_to_file( job_directory, "end" ) )
        return commands

    def job_properties( self, job_id, job_directory ):
        galaxy_slots_file = self.__galaxy_slots_file( job_directory )

        properties = {}
        properties[ GALAXY_SLOTS_KEY ] = self.__read_integer( galaxy_slots_file )
        start = self.__read_seconds_since_epoch( job_directory, "start" )
        end = self.__read_seconds_since_epoch( job_directory, "end" )
        if start is not None and end is not None:
            properties[ START_EPOCH_KEY ] = start
            properties[ END_EPOCH_KEY ] = end
            properties[ RUNTIME_SECONDS_KEY ] = end - start
        return properties

    def __record_galaxy_slots_command( self, job_directory ):
        galaxy_slots_file = self.__galaxy_slots_file( job_directory )
        return '''echo "$GALAXY_SLOTS" > '%s' ''' % galaxy_slots_file

    def __record_seconds_since_epoch_to_file( self, job_directory, name ):
        path = self._instrument_file_path( job_directory, "epoch_%s" % name )
        return 'date +"%s" > ' + path

    def __read_seconds_since_epoch( self, job_directory, name ):
        path = self._instrument_file_path( job_directory, "epoch_%s" % name )
        return self.__read_integer( path )

    def __galaxy_slots_file( self, job_directory ):
        return self._instrument_file_path( job_directory, "galaxy_slots" )

    def __read_integer( self, path ):
        value = None
        try:
            value = int( open( path, "r" ).read() )
        except Exception:
            pass
        return value


__all__ = ( 'CorePlugin', )
