from setuptools import setup, Command
from setuptools.command.install import install as orig_install
from distutils.command.install_data import install_data as orig_install_data
from distutils.command.build import build as orig_build

import fastentrypoints          # noqa: F401, import for side-effects!

from subprocess import call
import logging
from os import path, listdir
from glob import glob


# language files
po_source_folder = 'lang'
mo_build_prefix = path.join('build', 'locale')
mo_install_prefix = path.join('share', 'locale')

# completion files
comp_source_folder = 'completions'
comp_install_prefix = path.join('share', 'zsh', 'site-functions')

# menu icons
theme_base = path.join('share', 'icons', 'hicolor')
icon_names = ['mount', 'unmount', 'lock', 'unlock', 'eject', 'detach']


class build(orig_build):
    """Subclass build command to add a subcommand for building .mo files."""
    sub_commands = orig_build.sub_commands + [('build_mo', None)]


class build_mo(Command):

    """Create machine specific translation files (for i18n via gettext)."""

    description = 'Compile .po files into .mo files'

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        for po_filename in glob(path.join(po_source_folder, '*.po')):
            lang = path.splitext(path.split(po_filename)[1])[0]
            mo_filename = path.join(mo_build_prefix, lang,
                                    'LC_MESSAGES', 'udiskie.mo')
            self.mkpath(path.dirname(mo_filename))
            self.make_file(
                po_filename,
                mo_filename,
                self.make_mo,
                [po_filename, mo_filename])

    def make_mo(self, po_filename, mo_filename):
        """Create a machine object (.mo) from a portable object (.po) file."""
        try:
            call(['msgfmt', po_filename, '-o', mo_filename])
        except OSError as e:
            # ignore failures since i18n support is optional:
            logging.warning(e)


# NOTE: we want the install logic from *distutils* rather than the one from
# *setuptools*. distutils does NOT automatically install dependencies. On the
# other hand, setuptools fails to invoke the build commands properly before
# trying to install and it puts the data files in the egg directory (we want
# them in `sys.prefix` or similar).
# NOTE: Subclassing the setuptools install command alters its behaviour to use
# the distutils code. This is due to some really odd call-context checks in
# the setuptools command.
# NOTE: We need to subclass the setuptools install command rather than the
# distutils command to make installing with pip from the source distribution
# work.
class install(orig_install):

    """Custom install command used to update the gtk icon cache."""

    def run(self):
        """
        Perform old-style (distutils) install, then update GTK icon cache.

        Extends ``distutils.command.install.install.run``.
        """
        orig_install.run(self)
        try:
            call(['gtk-update-icon-cache', theme_base])
        except OSError as e:
            # ignore failures since the tray icon is an optional component:
            logging.warning(e)


class install_data(orig_install_data):

    def run(self):
        """Add built translation files and then install data files."""
        self.data_files += [
            (path.join(mo_install_prefix, lang, 'LC_MESSAGES'),
             [path.join(mo_build_prefix, lang, 'LC_MESSAGES', 'udiskie.mo')])
            for lang in listdir(mo_build_prefix)
        ]
        self.data_files += [
            (comp_install_prefix, [
                path.join(comp_source_folder, cmd)
                for cmd in listdir(comp_source_folder)
            ])
        ]
        orig_install_data.run(self)


setup(
    cmdclass={
        'install': install,
        'install_data': install_data,
        'build': build,
        'build_mo': build_mo,
    },
    data_files=[
        (path.join(theme_base, 'scalable', 'actions'), [
            path.join('icons', 'scalable', 'actions',
                      'udiskie-{0}.svg'.format(icon_name))
            for icon_name in icon_names])
    ],
)

@@ -98,85 +98,8 @@
 all%0A
-from distutils.command.install_data import install_data as orig_install_data%0A
 from
@@ -3157,175 +3157,23 @@
 )%0A%0A%0A
-class install_data(orig_install_data):%0A%0A    def run(self):%0A        %22%22%22Add built translation files and then install data files.%22%22%22%0A        self.data_files += %5B%0A        
+data_files = %5B%0A
     
@@ -3224,24 +3224,16 @@
 AGES'),%0A
-        
      %5Bpa
@@ -3302,100 +3302,348 @@
     
-        for lang in listdir(mo_build_prefix)%0A        %5D%0A        self.data_files += %5B%0A        
+for po_filename in glob(path.join(po_source_folder, '*.po'))%0A    for lang in %5Bpath.splitext(path.split(po_filename)%5B1%5D)%5B0%5D%5D%0A%5D%0A%0Adata_files += %5B%0A    (path.join(theme_base, 'scalable', 'actions'), %5B%0A        path.join('icons', 'scalable', 'actions',%0A                  'udiskie-%7B0%7D.svg'.format(icon_name))%0A        for icon_name in icon_names%5D),%0A
     
@@ -3670,32 +3670,24 @@
 , %5B%0A        
-     
-   
 path.join(co
@@ -3713,32 +3713,24 @@
 md)%0A        
-      
-  
 for cmd in l
@@ -3764,65 +3764,13 @@
     
-        %5D)%0A        %5D%0A        orig_install_data.run(self)%0A
+%5D),%0A%5D
 %0A%0Ase
@@ -3821,46 +3821,8 @@
 ll,%0A
-        'install_data': install_data,%0A
     
@@ -3897,227 +3897,18 @@
 les=
-%5B%0A        (path.join(theme_base, 'scalable', 'actions'), %5B%0A            path.join('icons', 'scalable', 'actions',%0A                      'udiskie-%7B0%7D.svg'.format(icon_name))%0A            for icon_name in icon_names%5D)%0A    %5D
+data_files
 ,%0A)%0A

Remove unecessary install_data command subclassing