#! /usr/bin/env python3

import importlib
import logging
import os
import subprocess

from setuptools import setup
from setuptools.command.install import install as install
from setuptools.command.develop import develop as develop


logger = logging.getLogger(__name__)


stan_model_files = [
    os.path.join("nonperiodic", "no-periodicity.stan"),
    os.path.join("nonperiodic", "start-high-high-low.stan"),
    os.path.join("nonperiodic", "start-high-low-high.stan"),
    os.path.join("periodic", "start-high-low-low.stan"),
    os.path.join("untranslated", "gaussian-naive-bayes.stan"),
    os.path.join("translated", "periodic-gaussian-mixture.stan")
]


stan_pickle_files = [
    os.path.join("nonperiodic", "no-periodicity.pkl"),
    os.path.join("nonperiodic", "start-high-high-low.pkl"),
    os.path.join("nonperiodic", "start-high-low-high.pkl"),
    os.path.join("periodic", "start-high-low-low.pkl"),
    os.path.join("untranslated", "gaussian-naive-bayes.pkl"),
    os.path.join("translated", "periodic-gaussian-mixture.pkl")
]


def _pickle_it(stan, pickle):

    import shlex

    dirname = os.path.dirname(pickle)
    if not os.path.exists(dirname):
        os.makedirs(dirname)

    cmd = "pickle-stan {} {}".format(shlex.quote(stan), shlex.quote(pickle))
    logging.info(cmd)
    subprocess.call(cmd, shell=True)


def _post_install(force_recompile):

    import site
    importlib.reload(site)

    import pbio.ribo.ribo_filenames as filenames
    import pbio.misc.shell_utils as shell_utils
    
    smf = [os.path.join("rpbp_models", s) for s in stan_model_files]

    models_base = filenames.get_default_models_base()
    spf = [os.path.join(models_base, s) for s in stan_pickle_files]

    # Compile and pickle the Stan models
    if force_recompile:
        for stan, pickle in zip(smf, spf):
            _pickle_it(stan, pickle)
    else:  # default
        for stan, pickle in zip(smf, spf):
            if os.path.exists(pickle):
                msg = "A model already exists at: {}. Skipping.".format(pickle)
                logging.warning(msg)
                continue
            _pickle_it(stan, pickle)

    # Check for the prerequisite programs
    programs = ['flexbar']
    shell_utils.check_programs_exist(programs, raise_on_error=False,
                                     package_name='flexbar', logger=logger)
        
    programs = ['STAR']
    shell_utils.check_programs_exist(programs, raise_on_error=False,
                                     package_name='STAR', logger=logger)

    programs = ['bowtie2', 'bowtie2-build-s']
    shell_utils.check_programs_exist(programs, raise_on_error=False,
                                     package_name='bowtie2', logger=logger)

    programs = ['samtools']
    shell_utils.check_programs_exist(programs, raise_on_error=False,
                                     package_name='SAMtools', logger=logger)


class SetupInstall(install):

    user_options = install.user_options + [
        ('force-recompile', None, 'Set this flag to recompile the Stan models'),
    ]

    def initialize_options(self):
        install.initialize_options(self)
        self.force_recompile = None

    def finalize_options(self):
        install.finalize_options(self)

    def run(self):
        force_recompile = self.force_recompile  # 0 or 1

        level = logging.getLevelName("INFO")
        logging.basicConfig(level=level,
                            format='%(levelname)-8s : %(message)s')

        install.run(self)
        # skip if RTD
        if not os.environ.get('READTHEDOCS') == 'True':
            _post_install(force_recompile)


class SetupDevelop(develop):

    user_options = develop.user_options + [
        ('force-recompile', None, 'Set this flag to recompile the Stan models'),
    ]

    def initialize_options(self):
        develop.initialize_options(self)
        self.force_recompile = None

    def finalize_options(self):
        develop.finalize_options(self)

    def run(self):
        force_recompile = self.force_recompile  # 0 or 1

        level = logging.getLevelName("INFO")
        logging.basicConfig(level=level,
                            format='%(levelname)-8s : %(message)s')

        develop.run(self)
        # skip if RTD
        if not os.environ.get('READTHEDOCS') == 'True':
            _post_install(force_recompile)


setup(
    cmdclass={
        'install': SetupInstall,
        'develop': SetupDevelop
    }
)

[((13, 9, 13, 36), 'logging.getLogger', 'logging.getLogger', ({(13, 27, 13, 35): '__name__'}, {}), '(__name__)', False, 'import logging\n'), ((144, 0, 149, 1), 'setuptools.setup', 'setup', (), '', False, 'from setuptools import setup\n'), ((17, 4, 17, 54), 'os.path.join', 'os.path.join', ({(17, 17, 17, 30): '"""nonperiodic"""', (17, 32, 17, 53): '"""no-periodicity.stan"""'}, {}), "('nonperiodic', 'no-periodicity.stan')", False, 'import os\n'), ((18, 4, 18, 59), 'os.path.join', 'os.path.join', ({(18, 17, 18, 30): '"""nonperiodic"""', (18, 32, 18, 58): '"""start-high-high-low.stan"""'}, {}), "('nonperiodic', 'start-high-high-low.stan')", False, 'import os\n'), ((19, 4, 19, 59), 'os.path.join', 'os.path.join', ({(19, 17, 19, 30): '"""nonperiodic"""', (19, 32, 19, 58): '"""start-high-low-high.stan"""'}, {}), "('nonperiodic', 'start-high-low-high.stan')", False, 'import os\n'), ((20, 4, 20, 55), 'os.path.join', 'os.path.join', ({(20, 17, 20, 27): '"""periodic"""', (20, 29, 20, 54): '"""start-high-low-low.stan"""'}, {}), "('periodic', 'start-high-low-low.stan')", False, 'import os\n'), ((21, 4, 21, 61), 'os.path.join', 'os.path.join', ({(21, 17, 21, 31): '"""untranslated"""', (21, 33, 21, 60): '"""gaussian-naive-bayes.stan"""'}, {}), "('untranslated', 'gaussian-naive-bayes.stan')", False, 'import os\n'), ((22, 4, 22, 64), 'os.path.join', 'os.path.join', ({(22, 17, 22, 29): '"""translated"""', (22, 31, 22, 63): '"""periodic-gaussian-mixture.stan"""'}, {}), "('translated', 'periodic-gaussian-mixture.stan')", False, 'import os\n'), ((27, 4, 27, 53), 'os.path.join', 'os.path.join', ({(27, 17, 27, 30): '"""nonperiodic"""', (27, 32, 27, 52): '"""no-periodicity.pkl"""'}, {}), "('nonperiodic', 'no-periodicity.pkl')", False, 'import os\n'), ((28, 4, 28, 58), 'os.path.join', 'os.path.join', ({(28, 17, 28, 30): '"""nonperiodic"""', (28, 32, 28, 57): '"""start-high-high-low.pkl"""'}, {}), "('nonperiodic', 'start-high-high-low.pkl')", False, 'import os\n'), ((29, 4, 29, 58), 'os.path.join', 'os.path.join', ({(29, 17, 29, 30): '"""nonperiodic"""', (29, 32, 29, 57): '"""start-high-low-high.pkl"""'}, {}), "('nonperiodic', 'start-high-low-high.pkl')", False, 'import os\n'), ((30, 4, 30, 54), 'os.path.join', 'os.path.join', ({(30, 17, 30, 27): '"""periodic"""', (30, 29, 30, 53): '"""start-high-low-low.pkl"""'}, {}), "('periodic', 'start-high-low-low.pkl')", False, 'import os\n'), ((31, 4, 31, 60), 'os.path.join', 'os.path.join', ({(31, 17, 31, 31): '"""untranslated"""', (31, 33, 31, 59): '"""gaussian-naive-bayes.pkl"""'}, {}), "('untranslated', 'gaussian-naive-bayes.pkl')", False, 'import os\n'), ((32, 4, 32, 63), 'os.path.join', 'os.path.join', ({(32, 17, 32, 29): '"""translated"""', (32, 31, 32, 62): '"""periodic-gaussian-mixture.pkl"""'}, {}), "('translated', 'periodic-gaussian-mixture.pkl')", False, 'import os\n'), ((40, 14, 40, 37), 'os.path.dirname', 'os.path.dirname', ({(40, 30, 40, 36): 'pickle'}, {}), '(pickle)', False, 'import os\n'), ((45, 4, 45, 21), 'logging.info', 'logging.info', ({(45, 17, 45, 20): 'cmd'}, {}), '(cmd)', False, 'import logging\n'), ((46, 4, 46, 36), 'subprocess.call', 'subprocess.call', (), '', False, 'import subprocess\n'), ((52, 4, 52, 26), 'importlib.reload', 'importlib.reload', ({(52, 21, 52, 25): 'site'}, {}), '(site)', False, 'import importlib\n'), ((59, 18, 59, 53), 'pbio.ribo.ribo_filenames.get_default_models_base', 'filenames.get_default_models_base', ({}, {}), '()', True, 'import pbio.ribo.ribo_filenames as filenames\n'), ((76, 4, 77, 75), 'pbio.misc.shell_utils.check_programs_exist', 'shell_utils.check_programs_exist', (), '', True, 'import pbio.misc.shell_utils as shell_utils\n'), ((80, 4, 81, 72), 'pbio.misc.shell_utils.check_programs_exist', 'shell_utils.check_programs_exist', (), '', True, 'import pbio.misc.shell_utils as shell_utils\n'), ((84, 4, 85, 75), 'pbio.misc.shell_utils.check_programs_exist', 'shell_utils.check_programs_exist', (), '', True, 'import pbio.misc.shell_utils as shell_utils\n'), ((88, 4, 89, 76), 'pbio.misc.shell_utils.check_programs_exist', 'shell_utils.check_programs_exist', (), '', True, 'import pbio.misc.shell_utils as shell_utils\n'), ((41, 11, 41, 34), 'os.path.exists', 'os.path.exists', ({(41, 26, 41, 33): 'dirname'}, {}), '(dirname)', False, 'import os\n'), ((42, 8, 42, 28), 'os.makedirs', 'os.makedirs', ({(42, 20, 42, 27): 'dirname'}, {}), '(dirname)', False, 'import os\n'), ((44, 37, 44, 54), 'shlex.quote', 'shlex.quote', ({(44, 49, 44, 53): 'stan'}, {}), '(stan)', False, 'import shlex\n'), ((44, 56, 44, 75), 'shlex.quote', 'shlex.quote', ({(44, 68, 44, 74): 'pickle'}, {}), '(pickle)', False, 'import shlex\n'), ((57, 11, 57, 41), 'os.path.join', 'os.path.join', ({(57, 24, 57, 37): '"""rpbp_models"""', (57, 39, 57, 40): 's'}, {}), "('rpbp_models', s)", False, 'import os\n'), ((60, 11, 60, 39), 'os.path.join', 'os.path.join', ({(60, 24, 60, 35): 'models_base', (60, 37, 60, 38): 's'}, {}), '(models_base, s)', False, 'import os\n'), ((99, 8, 99, 40), 'setuptools.command.install.install.initialize_options', 'install.initialize_options', ({(99, 35, 99, 39): 'self'}, {}), '(self)', True, 'from setuptools.command.install import install as install\n'), ((103, 8, 103, 38), 'setuptools.command.install.install.finalize_options', 'install.finalize_options', ({(103, 33, 103, 37): 'self'}, {}), '(self)', True, 'from setuptools.command.install import install as install\n'), ((108, 16, 108, 44), 'logging.getLevelName', 'logging.getLevelName', ({(108, 37, 108, 43): '"""INFO"""'}, {}), "('INFO')", False, 'import logging\n'), ((109, 8, 110, 67), 'logging.basicConfig', 'logging.basicConfig', (), '', False, 'import logging\n'), ((112, 8, 112, 25), 'setuptools.command.install.install.run', 'install.run', ({(112, 20, 112, 24): 'self'}, {}), '(self)', True, 'from setuptools.command.install import install as install\n'), ((125, 8, 125, 40), 'setuptools.command.develop.develop.initialize_options', 'develop.initialize_options', ({(125, 35, 125, 39): 'self'}, {}), '(self)', True, 'from setuptools.command.develop import develop as develop\n'), ((129, 8, 129, 38), 'setuptools.command.develop.develop.finalize_options', 'develop.finalize_options', ({(129, 33, 129, 37): 'self'}, {}), '(self)', True, 'from setuptools.command.develop import develop as develop\n'), ((134, 16, 134, 44), 'logging.getLevelName', 'logging.getLevelName', ({(134, 37, 134, 43): '"""INFO"""'}, {}), "('INFO')", False, 'import logging\n'), ((135, 8, 136, 67), 'logging.basicConfig', 'logging.basicConfig', (), '', False, 'import logging\n'), ((138, 8, 138, 25), 'setuptools.command.develop.develop.run', 'develop.run', ({(138, 20, 138, 24): 'self'}, {}), '(self)', True, 'from setuptools.command.develop import develop as develop\n'), ((68, 15, 68, 37), 'os.path.exists', 'os.path.exists', ({(68, 30, 68, 36): 'pickle'}, {}), '(pickle)', False, 'import os\n'), ((70, 16, 70, 36), 'logging.warning', 'logging.warning', ({(70, 32, 70, 35): 'msg'}, {}), '(msg)', False, 'import logging\n'), ((114, 15, 114, 44), 'os.environ.get', 'os.environ.get', ({(114, 30, 114, 43): '"""READTHEDOCS"""'}, {}), "('READTHEDOCS')", False, 'import os\n'), ((140, 15, 140, 44), 'os.environ.get', 'os.environ.get', ({(140, 30, 140, 43): '"""READTHEDOCS"""'}, {}), "('READTHEDOCS')", False, 'import os\n')]