#! /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
    }
)

[((242, 269), 'logging.getLogger', 'logging.getLogger', (['__name__'], {}), '(__name__)\n', (259, 269), False, 'import logging\n'), ((4350, 4416), 'setuptools.setup', 'setup', ([], {'cmdclass': "{'install': SetupInstall, 'develop': SetupDevelop}"}), "(cmdclass={'install': SetupInstall, 'develop': SetupDevelop})\n", (4355, 4416), False, 'from setuptools import setup\n'), ((297, 347), 'os.path.join', 'os.path.join', (['"""nonperiodic"""', '"""no-periodicity.stan"""'], {}), "('nonperiodic', 'no-periodicity.stan')\n", (309, 347), False, 'import os\n'), ((353, 408), 'os.path.join', 'os.path.join', (['"""nonperiodic"""', '"""start-high-high-low.stan"""'], {}), "('nonperiodic', 'start-high-high-low.stan')\n", (365, 408), False, 'import os\n'), ((414, 469), 'os.path.join', 'os.path.join', (['"""nonperiodic"""', '"""start-high-low-high.stan"""'], {}), "('nonperiodic', 'start-high-low-high.stan')\n", (426, 469), False, 'import os\n'), ((475, 526), 'os.path.join', 'os.path.join', (['"""periodic"""', '"""start-high-low-low.stan"""'], {}), "('periodic', 'start-high-low-low.stan')\n", (487, 526), False, 'import os\n'), ((532, 589), 'os.path.join', 'os.path.join', (['"""untranslated"""', '"""gaussian-naive-bayes.stan"""'], {}), "('untranslated', 'gaussian-naive-bayes.stan')\n", (544, 589), False, 'import os\n'), ((595, 655), 'os.path.join', 'os.path.join', (['"""translated"""', '"""periodic-gaussian-mixture.stan"""'], {}), "('translated', 'periodic-gaussian-mixture.stan')\n", (607, 655), False, 'import os\n'), ((686, 735), 'os.path.join', 'os.path.join', (['"""nonperiodic"""', '"""no-periodicity.pkl"""'], {}), "('nonperiodic', 'no-periodicity.pkl')\n", (698, 735), False, 'import os\n'), ((741, 795), 'os.path.join', 'os.path.join', (['"""nonperiodic"""', '"""start-high-high-low.pkl"""'], {}), "('nonperiodic', 'start-high-high-low.pkl')\n", (753, 795), False, 'import os\n'), ((801, 855), 'os.path.join', 'os.path.join', (['"""nonperiodic"""', '"""start-high-low-high.pkl"""'], {}), "('nonperiodic', 'start-high-low-high.pkl')\n", (813, 855), False, 'import os\n'), ((861, 911), 'os.path.join', 'os.path.join', (['"""periodic"""', '"""start-high-low-low.pkl"""'], {}), "('periodic', 'start-high-low-low.pkl')\n", (873, 911), False, 'import os\n'), ((917, 973), 'os.path.join', 'os.path.join', (['"""untranslated"""', '"""gaussian-naive-bayes.pkl"""'], {}), "('untranslated', 'gaussian-naive-bayes.pkl')\n", (929, 973), False, 'import os\n'), ((979, 1038), 'os.path.join', 'os.path.join', (['"""translated"""', '"""periodic-gaussian-mixture.pkl"""'], {}), "('translated', 'periodic-gaussian-mixture.pkl')\n", (991, 1038), False, 'import os\n'), ((1106, 1129), 'os.path.dirname', 'os.path.dirname', (['pickle'], {}), '(pickle)\n', (1121, 1129), False, 'import os\n'), ((1277, 1294), 'logging.info', 'logging.info', (['cmd'], {}), '(cmd)\n', (1289, 1294), False, 'import logging\n'), ((1299, 1331), 'subprocess.call', 'subprocess.call', (['cmd'], {'shell': '(True)'}), '(cmd, shell=True)\n', (1314, 1331), False, 'import subprocess\n'), ((1391, 1413), 'importlib.reload', 'importlib.reload', (['site'], {}), '(site)\n', (1407, 1413), False, 'import importlib\n'), ((1605, 1640), 'pbio.ribo.ribo_filenames.get_default_models_base', 'filenames.get_default_models_base', ([], {}), '()\n', (1638, 1640), True, 'import pbio.ribo.ribo_filenames as filenames\n'), ((2211, 2318), 'pbio.misc.shell_utils.check_programs_exist', 'shell_utils.check_programs_exist', (['programs'], {'raise_on_error': '(False)', 'package_name': '"""flexbar"""', 'logger': 'logger'}), "(programs, raise_on_error=False,\n    package_name='flexbar', logger=logger)\n", (2243, 2318), True, 'import pbio.misc.shell_utils as shell_utils\n'), ((2389, 2493), 'pbio.misc.shell_utils.check_programs_exist', 'shell_utils.check_programs_exist', (['programs'], {'raise_on_error': '(False)', 'package_name': '"""STAR"""', 'logger': 'logger'}), "(programs, raise_on_error=False,\n    package_name='STAR', logger=logger)\n", (2421, 2493), True, 'import pbio.misc.shell_utils as shell_utils\n'), ((2578, 2685), 'pbio.misc.shell_utils.check_programs_exist', 'shell_utils.check_programs_exist', (['programs'], {'raise_on_error': '(False)', 'package_name': '"""bowtie2"""', 'logger': 'logger'}), "(programs, raise_on_error=False,\n    package_name='bowtie2', logger=logger)\n", (2610, 2685), True, 'import pbio.misc.shell_utils as shell_utils\n'), ((2752, 2860), 'pbio.misc.shell_utils.check_programs_exist', 'shell_utils.check_programs_exist', (['programs'], {'raise_on_error': '(False)', 'package_name': '"""SAMtools"""', 'logger': 'logger'}), "(programs, raise_on_error=False,\n    package_name='SAMtools', logger=logger)\n", (2784, 2860), True, 'import pbio.misc.shell_utils as shell_utils\n'), ((1141, 1164), 'os.path.exists', 'os.path.exists', (['dirname'], {}), '(dirname)\n', (1155, 1164), False, 'import os\n'), ((1174, 1194), 'os.makedirs', 'os.makedirs', (['dirname'], {}), '(dirname)\n', (1185, 1194), False, 'import os\n'), ((1233, 1250), 'shlex.quote', 'shlex.quote', (['stan'], {}), '(stan)\n', (1244, 1250), False, 'import shlex\n'), ((1252, 1271), 'shlex.quote', 'shlex.quote', (['pickle'], {}), '(pickle)\n', (1263, 1271), False, 'import shlex\n'), ((1528, 1558), 'os.path.join', 'os.path.join', (['"""rpbp_models"""', 's'], {}), "('rpbp_models', s)\n", (1540, 1558), False, 'import os\n'), ((1652, 1680), 'os.path.join', 'os.path.join', (['models_base', 's'], {}), '(models_base, s)\n', (1664, 1680), False, 'import os\n'), ((3100, 3132), 'setuptools.command.install.install.initialize_options', 'install.initialize_options', (['self'], {}), '(self)\n', (3126, 3132), True, 'from setuptools.command.install import install as install\n'), ((3210, 3240), 'setuptools.command.install.install.finalize_options', 'install.finalize_options', (['self'], {}), '(self)\n', (3234, 3240), True, 'from setuptools.command.install import install as install\n'), ((3335, 3363), 'logging.getLevelName', 'logging.getLevelName', (['"""INFO"""'], {}), "('INFO')\n", (3355, 3363), False, 'import logging\n'), ((3372, 3444), 'logging.basicConfig', 'logging.basicConfig', ([], {'level': 'level', 'format': '"""%(levelname)-8s : %(message)s"""'}), "(level=level, format='%(levelname)-8s : %(message)s')\n", (3391, 3444), False, 'import logging\n'), ((3482, 3499), 'setuptools.command.install.install.run', 'install.run', (['self'], {}), '(self)\n', (3493, 3499), True, 'from setuptools.command.install import install as install\n'), ((3827, 3859), 'setuptools.command.develop.develop.initialize_options', 'develop.initialize_options', (['self'], {}), '(self)\n', (3853, 3859), True, 'from setuptools.command.develop import develop as develop\n'), ((3937, 3967), 'setuptools.command.develop.develop.finalize_options', 'develop.finalize_options', (['self'], {}), '(self)\n', (3961, 3967), True, 'from setuptools.command.develop import develop as develop\n'), ((4062, 4090), 'logging.getLevelName', 'logging.getLevelName', (['"""INFO"""'], {}), "('INFO')\n", (4082, 4090), False, 'import logging\n'), ((4099, 4171), 'logging.basicConfig', 'logging.basicConfig', ([], {'level': 'level', 'format': '"""%(levelname)-8s : %(message)s"""'}), "(level=level, format='%(levelname)-8s : %(message)s')\n", (4118, 4171), False, 'import logging\n'), ((4209, 4226), 'setuptools.command.develop.develop.run', 'develop.run', (['self'], {}), '(self)\n', (4220, 4226), True, 'from setuptools.command.develop import develop as develop\n'), ((1934, 1956), 'os.path.exists', 'os.path.exists', (['pickle'], {}), '(pickle)\n', (1948, 1956), False, 'import os\n'), ((2054, 2074), 'logging.warning', 'logging.warning', (['msg'], {}), '(msg)\n', (2069, 2074), False, 'import logging\n'), ((3537, 3566), 'os.environ.get', 'os.environ.get', (['"""READTHEDOCS"""'], {}), "('READTHEDOCS')\n", (3551, 3566), False, 'import os\n'), ((4264, 4293), 'os.environ.get', 'os.environ.get', (['"""READTHEDOCS"""'], {}), "('READTHEDOCS')\n", (4278, 4293), False, 'import os\n')]