#!python
import os, sys, logging
import argparse
from ipypublish.main import publish
from ipypublish.scripts import export_plugins
                
def nbpublish(ipynb_path,
              outformat='latex_ipypublish_main',
              outpath=None, dump_files=False,
              ignore_prefix='_',
              create_pdf=False, pdf_in_temp=False, pdf_debug=False,
              log_level='INFO'):
    """ convert one or more Jupyter notebooks to a published format

    paths can be string of an existing file or folder,
    or a pathlib.Path like object
              
    Parameters
    ----------
    ipynb_path
        notebook file or directory
    outformat: str
        output format to use
    outpath : path_like
        path to output converted files
    dump_files: bool
        write files from nbconvert (containing images, etc) to outpath
    ignore_prefix: str
        ignore ipynb files with this prefix                
    create_pdf: bool
        convert to pdf (if converting to latex)
    pdf_in_temp: bool
        run pdf conversion in a temporary folder and only copy back the .pdf file
    pdf_debug: bool
        run latexmk in interactive mode
    loglevel: str
        the logging level (debug, info, critical, ...)
              
    """
    ipynb_name = os.path.splitext(os.path.basename(ipynb_path))[0]
    outdir = os.path.join(os.getcwd(),'converted') if outpath is None else outpath 
    if not os.path.exists(outdir):
      os.mkdir(outdir)
              
    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)
    slogger.propogate = False
    root.addHandler(slogger)
    flogger = logging.FileHandler(os.path.join(outdir,ipynb_name+'.nbpub.log'), 'w')
    flogger.setLevel(getattr(logging,log_level.upper()))
    flogger.setFormatter(formatter)
    flogger.propogate = False
    root.addHandler(flogger)

    return publish(ipynb_path,
                  outformat=outformat,
                  outpath=outpath, dump_files=dump_files,
                  ignore_prefix=ignore_prefix,
                  create_pdf=create_pdf, pdf_in_temp=pdf_in_temp, pdf_debug=pdf_debug) 

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()):
        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='convert one or more Jupyter notebooks to a published format',
        epilog=list_outformats(),
        formatter_class=CustomFormatter
    )
    parser.add_argument("filepath", type=str, 
                        help='notebook file or directory', metavar='filepath')
    parser.add_argument("-f","--outformat", type=str, 
                        choices=list(plugins.keys()), metavar='str',
                        help='output format to use (see available below)', default='latex_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("-i","--ignore-prefix", type=str, metavar='str',
                        help='ignore ipynb files with this prefix',
                        default='_')
    parser.add_argument("-pdf","--create-pdf", action="store_true",
                        help='convert to pdf (only if converting to latex)')
    parser.add_argument("-ptemp","--pdf-in-temp", action="store_true",
                        help='run pdf conversion in a temporary folder and only copy back the .pdf file')
    parser.add_argument("-pbug","--pdf-debug", action="store_true",
                        help='run latexmk in interactive mode')
    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')
    nbpublish(filepath, **options)   
        
        