# -*- coding: utf-8 -*-
'''
    pytestsalt.utils.cli_scripts
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Code to generate Salt CLI scripts for test runs
'''

# Import Python Libs
from __future__ import absolute_import, unicode_literals
import os
import stat
import logging
import textwrap

log = logging.getLogger(__name__)

ROOT_DIR = os.path.dirname(os.path.dirname(__file__))

SCRIPT_TEMPLATES = {
    'salt': textwrap.dedent(
        '''
        from salt.scripts import salt_main

        if __name__ == '__main__':
            salt_main()
        '''
    ),
    'salt-api': textwrap.dedent(
        '''
        import salt.cli

        def main():
            sapi = salt.cli.SaltAPI()
            sapi.start()

        if __name__ == '__main__':
            main()'
        '''
    ),
    'common': textwrap.dedent(
        '''
        from salt.scripts import salt_{0}
        import salt.utils.platform

        def main():
            if salt.utils.platform.is_windows():
                import os.path
                import py_compile
                cfile = os.path.splitext(__file__)[0] + '.pyc'
                if not os.path.exists(cfile):
                    py_compile.compile(__file__, cfile)
            salt_{0}()

        if __name__ == '__main__':
            main()
        '''
    ),
    'coverage': textwrap.dedent(
        '''
        # Setup coverage environment variables
        COVERAGE_FILE = os.path.join(CODE_DIR, '.coverage')
        COVERAGE_PROCESS_START = os.path.join(CODE_DIR, '.coveragerc')
        os.environ[str('COVERAGE_FILE')] = str(COVERAGE_FILE)
        os.environ[str('COVERAGE_PROCESS_START')] = str(COVERAGE_PROCESS_START)
        '''
    ),
    'sitecustomize': textwrap.dedent(
        '''
        # Allow sitecustomize.py to be importable for test coverage purposes
        SITECUSTOMIZE_DIR = r'{sitecustomize_dir}'
        PYTHONPATH = os.environ.get('PYTHONPATH') or None
        if PYTHONPATH is None:
            PYTHONPATH_ENV_VAR = SITECUSTOMIZE_DIR
        else:
            PYTHON_PATH_ENTRIES = PYTHONPATH.split(os.pathsep)
            if SITECUSTOMIZE_DIR in PYTHON_PATH_ENTRIES:
                PYTHON_PATH_ENTRIES.remove(SITECUSTOMIZE_DIR)
            PYTHON_PATH_ENTRIES.insert(0, SITECUSTOMIZE_DIR)
            PYTHONPATH_ENV_VAR = os.pathsep.join(PYTHON_PATH_ENTRIES)
        os.environ[str('PYTHONPATH')] = str(PYTHONPATH_ENV_VAR)
        if SITECUSTOMIZE_DIR in sys.path:
            sys.path.remove(SITECUSTOMIZE_DIR)
        sys.path.insert(0, SITECUSTOMIZE_DIR)
        '''
    )
}


def generate_script(bin_dir,
                    script_name,
                    executable,
                    code_dir,
                    extra_code=None,
                    inject_coverage=False,
                    inject_sitecustomize=False):
    '''
    Generate script
    '''
    # Late import
    import pytestsalt.utils.compat as compat

    if not os.path.isdir(bin_dir):
        os.makedirs(bin_dir)

    cli_script_name = 'cli_{}.py'.format(script_name.replace('-', '_'))
    script_path = os.path.join(bin_dir, cli_script_name)

    if not os.path.isfile(script_path):
        log.info('Generating %s', script_path)

        with compat.fopen(script_path, 'w') as sfh:
            script_template = SCRIPT_TEMPLATES.get(script_name, None)
            if script_template is None:
                script_template = SCRIPT_TEMPLATES.get('common', None)
            if script_template is None:
                raise RuntimeError(
                    'Pytest Salt\'s does not know how to handle the {} script'.format(
                        script_name
                    )
                )

            if len(executable) > 128:
                # Too long for a shebang, let's use /usr/bin/env and hope
                # the right python is picked up
                executable = '/usr/bin/env python'

            script_contents = textwrap.dedent(
                '''
                #!{executable}

                from __future__ import absolute_import
                import os
                import sys

                CODE_DIR = r'{code_dir}'
                if CODE_DIR in sys.path:
                    sys.path.remove(CODE_DIR)
                sys.path.insert(0, CODE_DIR)
                '''.format(
                    executable=executable,
                    code_dir=code_dir,
                )
            )

            if extra_code:
                script_contents += '\n' + extra_code + '\n'

            if inject_coverage:
                script_contents += '\n' + SCRIPT_TEMPLATES['coverage'] + '\n'

            if inject_sitecustomize:
                script_contents += '\n{}\n'.format(
                    SCRIPT_TEMPLATES['sitecustomize'].format(
                        sitecustomize_dir=os.path.join(
                            ROOT_DIR, 'salt', 'coverage'
                        )
                    )
                )

            script_contents += '\n' + script_template.format(script_name.replace('salt-', ''))
            sfh.write(script_contents.strip())
            log.debug(
                'Wrote the following contents to temp script %s:\n%s',
                script_path,
                script_contents
            )
        fst = os.stat(script_path)
        os.chmod(script_path, fst.st_mode | stat.S_IEXEC)

    log.info('Returning script path %r', script_path)
    return script_path
