# Copyright (c) 2009 ActiveState Software Inc.
# See http://www.activestate.com/activepython/license/ for licensing
# information.

import os
import sys
import logging

from pypm.client.base import PyPMFeature, ImagePythonEnvironment
from pypm.client.fs import Extractor

LOG = logging.getLogger(__name__)


class Fixer(PyPMFeature):

    class ScriptShebangFixer(object):
        """Fix #! hardcoding in scripts

        While running ``easy_install $pkg.name`` is `one solution`_, it will not
        work with packages that use only distutils (not setuptools).

        Note: On Windows, foo.exe uses the shebang line from foo-script.py; so
        we should run this fixer on Windows too.

        .. _`one solution`:
        http://mail.python.org/pipermail/distutils-sig/2008-April/009283.html
        """

        def __init__(self, pypmenv, ipkg):
            self.pypmenv = pypmenv
            self.ipkg = ipkg

            assert os.path.exists(self.pypmenv.pyenv.python_exe)

        @staticmethod
        def applicable():
            return True

        def fix(self):
            pyenv = self.pypmenv.pyenv
            if isinstance(pyenv, ImagePythonEnvironment):
                python_exe = pyenv.target_python_exe
                LOG.info('using ImagePythonEnvironment w/ target=%s', python_exe)
            else:
                python_exe = pyenv.python_exe
                
            for path in self.ipkg.files_list:
                if path.startswith('bin/') or (path.startswith('Scripts/') and
                                               not path.endswith('.exe')):
                    self._fix_script(pyenv.get_abspath(path), python_exe)

        @staticmethod
        def _fix_script(script_path, python_exe):
            # replace old #! path with ``python_exe``
            with open(script_path) as file:
                first_line = file.readline()
                if first_line.startswith('#!'):
                    contents = file.read()
                    file.close()

                    first_line = '#!' + python_exe
                    LOG.info('Fixing script %s', script_path)
                    LOG.debug('New shebang %s', first_line)
                    with open(script_path, 'w') as wfile:
                        wfile.write(first_line + '\n')
                        wfile.write(contents)
                        wfile.flush()

        def __str__(self):
            return "<ScriptShebangFixer:%s,%s>" % (self.ipkg.name,
                                                   self.pypmenv.pyenv.root_dir)

    available_fixers = [ScriptShebangFixer]

    def get_applicable_fixers(self, ipkg):
        return [Fixer(self.pypmenv, ipkg)
                for Fixer in self.available_fixers if Fixer.applicable()]

