#!python
import sys, os, logging
import argparse
from ipypublish.scripts.reveal_serve import RevealServer
from ipypublish.main import publish
from ipypublish.scripts import export_plugins

def nbpresent(inpath, 
              outformat='slides_standard',
              outpath=None, dump_files=False,
              ignore_prefix='_',
              log_level='INFO'):
    """ load reveal.js slides as a web server, converting from ipynb first if path extension is .ipynb
    
    Parameters
    ----------
    inpath: str
        path to html or ipynb file
    outformat: str
        conversion format to use
    outpath : path_like
        path to output converted files
    dump_files: bool
        whether to write files from nbconvert (containing images, etc) to outpath
    ignore_prefix: str
        ignore ipynb files with this prefix                
    loglevel: str
        the logging level (debug, info, critical, ...)
    
    """
    root = logging.getLogger()
    root.handlers = [] # remove any existing handlers
    root.setLevel(logging.DEBUG)
    slogger = logging.StreamHandler(sys.stdout)
    slogger.setLevel(getattr(logging,log_level.upper()))
    formatter = logging.Formatter('%(levelname)s:%(module)s:%(message)s')
    slogger.setFormatter(formatter)
    root.addHandler(slogger)
    
    inpath_name, inpath_ext  = os.path.splitext(os.path.basename(inpath))
    print(inpath_ext)
    if inpath_ext == '.ipynb':
        outdir = os.path.join(os.getcwd(),'converted') if outpath is None else outpath 
        if not os.path.exists(outdir):
            os.mkdir(outdir)
        flogger = logging.FileHandler(os.path.join(outdir,inpath_name+'.nbpub.log'), 'w')
        flogger.setLevel(getattr(logging,log_level.upper()))
        root.addHandler(flogger)
        inpath  = publish(inpath,
                          outformat=outformat,
                          outpath=outpath, dump_files=dump_files,
                          ignore_prefix=ignore_prefix,
                          create_pdf=False)

    server = RevealServer()
    server.serve(inpath)

def list_outformats():
    """ print list all available output formats and descriptions
    
    Parameters
    ----------
    type: str
        list for a specific type (Html, Latex, Slide, ...)
    """
    plugins = export_plugins.get()
    outstr = 'Available Output Formats\n'
    outstr +='------------------------'
    for plugin_name in sorted(plugins.keys()):
        if not plugins[plugin_name]['oformat'].lower() == 'slides':
            continue
        outstr += '\n- {}:'.format(plugin_name)
        space = '  '
        for line in plugins[plugin_name]['descript'].split('\n'):
            outstr += '\n' + space + line
        
    return outstr

class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, 
                     argparse.RawDescriptionHelpFormatter,
                     ):
    pass
    
class MyParser(argparse.ArgumentParser):
    def error(self, message):
        sys.stderr.write('error: %s\n' % message)
        self.print_help()
        sys.exit(2)
    
if __name__ == '__main__':
    
    local_plugin_dir = os.path.join(os.getcwd(),'ipypublish_plugins')
    if os.path.exists(local_plugin_dir):
        load_errors = export_plugins.add_directory(local_plugin_dir)
        if load_errors:
            raise IOError('errors in loading external plugins: {}'.format('\n'.join(['{0}: {1}'.format(a,b) for a,b in load_errors])))
    
    plugins = export_plugins.get()

    parser = MyParser(
        description='load reveal.js slides as a web server,\nconverting from ipynb first if path extension is .ipynb',
        epilog=list_outformats(),
        formatter_class=CustomFormatter
    )

    parser.add_argument("filepath", type=str, 
                        help='path to html or ipynb file', metavar='filepath')
    parser.add_argument("-f","--outformat", type=str, 
                        choices=list(plugins.keys()), metavar='str',
                        help='output format to use (see available below)', 
                        default='slides_ipypublish_main')
    parser.add_argument("-o","--outpath", type=str, metavar='str',
                        help='path to output converted files', 
                        default=os.path.join(os.getcwd(),'converted'))
    parser.add_argument("-d","--dump-files", action="store_true",
                        help='dump external files, linked to in the document, into the outpath')
    parser.add_argument("-log","--log-level", type=str, default='info',
                        choices=['debug','info','warning','error'],
                        help='the logging level to output to screen/file')

    args = parser.parse_args()
    
    options = vars(args)
    filepath = options.pop('filepath')
    nbpresent(filepath, **options)   
