#-*- conding: utf-8 -*-

import os
import warnings
import logging

logger = logging.getLogger('RMD_READER')

from pelican import readers
from pelican import signals
from pelican import settings

KNITR = None
RMD = False
FIG_PATH = None
R_STARTED = False

def startr():
    global KNITR, R_OBJECTS, R_STARTED
    if R_STARTED:
        return
    logger.debug('STARTING R')
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        try:
            import rpy2.rinterface
            rpy2.rinterface.set_initoptions((b'rpy2', b'--no-save', b'--vanilla', b'--quiet'))
        except AttributeError:
            from rpy2.rinterface_lib import embedded
            embedded.set_initoptions(("rpy2", "--no-save", "--vanilla", "--quiet"))
        import rpy2.robjects as R_OBJECTS
        from rpy2.robjects.packages import importr
    KNITR = importr('knitr')
    logger.debug('R STARTED')
    R_STARTED = True

def initsignal(pelicanobj):
    global RMD, FIG_PATH
    try:
        startr()
        
        idx = KNITR.opts_knit.names.index('set')
        path = pelicanobj.settings.get('PATH','%s/content' % settings.DEFAULT_CONFIG.get('PATH'))
        logger.debug("RMD_READER PATH = %s", path)
        KNITR.opts_knit[idx](**{'base.dir': path})
        
        knitroptsknit = pelicanobj.settings.get('RMD_READER_KNITR_OPTS_KNIT', None)
        if knitroptsknit:
            KNITR.opts_knit[idx](**{str(k): v for k,v in knitroptsknit.items()})
        
        idx = KNITR.opts_chunk.names.index('set')
        knitroptschunk = pelicanobj.settings.get('RMD_READER_KNITR_OPTS_CHUNK', None)
        if knitroptschunk:
            FIG_PATH = knitroptschunk['fig.path'] if 'fig.path' in knitroptschunk else 'figure/'
            KNITR.opts_chunk[idx](**{str(k): v for k,v in knitroptschunk.items()})
        
        RMD = True
    except ImportError as ex:
        RMD = False

class RmdReader(readers.BaseReader):
    file_extensions = ['Rmd', 'rmd']

    @property
    def enabled(self):
        return RMD

    # You need to have a read method, which takes a filename and returns
    # some content and the associated metadata.
    def read(self, filename):
        """Parse content and metadata of markdown files"""
        QUIET = self.settings.get('RMD_READER_KNITR_QUIET', True)
        ENCODING = self.settings.get('RMD_READER_KNITR_ENCODING', 'UTF-8')
        CLEANUP = self.settings.get('RMD_READER_CLEANUP', True)
        RENAME_PLOT = self.settings.get('RMD_READER_RENAME_PLOT', 'chunklabel')
        if type(RENAME_PLOT) is bool:
            logger.error("RMD_READER_RENAME_PLOT takes a string value (either chunklabel or directory), please see the readme.")
            if RENAME_PLOT:
                RENAME_PLOT = 'chunklabel'
                logger.error("Defaulting to chunklabel")
            else:
                RENAME_PLOT = 'disabled'
                logger.error("Disabling plot renaming")
        logger.debug("RMD_READER_KNITR_QUIET = %s", QUIET)
        logger.debug("RMD_READER_KNITR_ENCODING = %s", ENCODING)
        logger.debug("RMD_READER_CLEANUP = %s", CLEANUP)
        logger.debug("RMD_READER_RENAME_PLOT = %s", RENAME_PLOT)
        # replace single backslashes with double backslashes
        filename = filename.replace('\\', '\\\\')
        # parse Rmd file - generate md file
        md_filename = filename.replace('.Rmd', '.aux').replace('.rmd', '.aux')
        if RENAME_PLOT == 'chunklabel' or RENAME_PLOT == 'directory':
            if RENAME_PLOT == 'chunklabel':
                chunk_label = os.path.splitext(os.path.basename(filename))[0]
                logger.debug('Chunk label: %s', chunk_label)
            elif RENAME_PLOT == 'directory':
                chunk_label = 'unnamed-chunk'
                PATH = self.settings.get('PATH','%s/content' % settings.DEFAULT_CONFIG.get('PATH'))
                src_name = os.path.splitext(os.path.relpath(filename, PATH))[0]
                idx = KNITR.opts_chunk.names.index('set')
                knitroptschunk = { 'fig.path': '%s-' % os.path.join(FIG_PATH, src_name) }
                KNITR.opts_chunk[idx](**{str(k): v for k,v in knitroptschunk.items()})
                logger.debug('Figures path: %s, chunk label: %s', knitroptschunk['fig.path'], chunk_label)
            R_OBJECTS.r('''
opts_knit$set(unnamed.chunk.label="{unnamed_chunk_label}")
render_markdown()
hook_plot <- knit_hooks$get('plot')
knit_hooks$set(plot=function(x, options) hook_plot(paste0("{{static}}/", x), options))
            '''.format(unnamed_chunk_label=chunk_label))
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            KNITR.knit(filename, md_filename, quiet=QUIET, encoding=ENCODING)
        # read md file - create a MarkdownReader
        md_reader = readers.MarkdownReader(self.settings)
        content, metadata = md_reader.read(md_filename)
        # remove md file
        if CLEANUP:
            os.remove(md_filename)
        return content, metadata

def add_reader(readers):
    readers.reader_classes['rmd'] = RmdReader

def register():
    signals.readers_init.connect(add_reader)
    signals.initialized.connect(initsignal)
