# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/rpy.ipynb (unless otherwise specified).

__all__ = ['logger', 'source', 'pkg_name', 'utils', 'types', 'DTYPES', 'AS_DTYPE', 'IntArray', 'FloatArray', 'Int',
           'Float']

# Cell
import rpy2
from rpy2 import rinterface
from rpy2.robjects import packages
from rpy2.robjects import numpy2ri, pandas2ri
import rpy2.situation
from traittypes import Array
from traitlets import TraitType, HasTraits, Unicode
import traitlets
import configparser
import os
import numpy as np
import subprocess

# Cell
from .globals import CONFIG, DEFINITIONS, HANDLER, APP_DIR
logger = HANDLER.getLogger(__name__)

# Cell
source=None
if CONFIG and 'R' in CONFIG:
    if 'lib_loc' in CONFIG['R']:
        lib_loc = CONFIG['R']['lib_loc']
    if 'source' in CONFIG['R']:
        source_path = os.path.expanduser(CONFIG['R']['source'])
        if not os.path.isfile(source_path):
            logger.warning('Source file for Superpower library given in config.ini is invalid. Defaulting to internal copy.')
        else:
            source = source_path
            logger.info('Superpower source file found at %s' % source)
if not source:
    source = os.path.join(APP_DIR, DEFINITIONS['R']['source'])

# Cell
pkg_name='Superpower'
utils = packages.importr('utils')
try: # to import Superpower
    if lib_loc:
        logger.info('Attempting Superpower install with library location %s...' % lib_loc)
        SUPERPOWER = packages.importr(pkg_name, lib_loc=lib_loc)
    else:
        lib_loc = rpy2.situation.get_r_home()
        logger.info('Attempting Superpower install from %s...' % lib_loc)
        SUPERPOWER = packages.importr(pkg_name, lib_loc)
except Exception as e:
    logger.exception('Superpower import attempt failed with message: %s' % str(e))
    logger.info('Attempting install of %s with library location %s' % (source, lib_loc))
    try:
        kwargs = {}
        kwargs['pkgs'] = source
        kwargs['repos'] = rinterface.NULL
        kwargs['type'] = 'source'
        utils.install_packages(**kwargs)
        SUPERPOWER = packages.importr(pkg_name)
    except:
        logger.exception('Install failed.')
        raise Exception('Fatal. Superpower could not be imported or installed.')
        """try: # to install from command line and print stderr for failure info
            ret = subprocess.run(["R", "CMD", "INSTALL", kwargs['pkgs']], capture_output=True)
            ret.check_returncode()
            SUPERPOWER = packages.importr(pkg_name)
        except:
            print(ret.stdout)
            print(ret.stderr)
            raise"""

# Cell
assert SUPERPOWER, 'Superpower install was unsuccessful'
rinterface.initr()
numpy2ri.activate()
pandas2ri.activate()

# Cell
# https://rpy2.github.io/doc/v3.0.x/html/rinterface.html#index-19
types = (('int', rinterface.IntSexpVector([])), ('bool', rinterface.BoolSexpVector([])), ('string', rinterface.StrSexpVector([])), ('float', rinterface.FloatSexpVector([])))
DTYPES = {}
AS_DTYPE = {}
for py_type, r_vector in types:
    np_array = np.asarray(r_vector)
    DTYPES[py_type] = np_array.dtype
    AS_DTYPE[py_type] = getattr(np, str(np_array.dtype))

# Cell
class IntArray(Array):
    def __init__(self, default_value=None, size=None, **kwargs):
        if size:
            assert 'default_value' not in kwargs, "Only one of 'size' or 'default_value' should be provided"
            kwargs['default_value'] = np.empty(size, dtype=DTYPES['int'])
        if default_value is not None:
            kwargs['default_value'] = default_value
        super().__init__(dtype=DTYPES['int'], **kwargs)

# Cell
class FloatArray(Array):
    def __init__(self, default_value=None, size=None, **kwargs):
        if size:
            assert 'default_value' not in kwargs, "Only one of 'size' or 'default_value' should be provided"
            kwargs['default_value'] = np.empty(size, dtype=DTYPES['float'])
        if default_value is not None:
            kwargs['default_value'] = default_value
        super().__init__(dtype=DTYPES['float'], **kwargs)

# Cell
class Int(TraitType):

    info_text = 'an integer compatible with R and numpy'

    def validate(self, obj, value):
        if isinstance(value, int) or (hasattr(value, 'dtype') and np.issubdtype(value.dtype, np.integer)):
            return AS_DTYPE['int'](value)
        self.error(obj, value)

# Cell
class Float(TraitType):

    info_text = 'an integer compatible with R and numpy'

    def validate(self, obj, value):
        if isinstance(value, int) or isinstance(value, float) or (hasattr(value, 'dtype') and np.issubdtype(value.dtype, np.floating)):
            return AS_DTYPE['float'](value)
        self.error(obj, value)