#!/usr/bin/python
#
# Copyright 2010-2012 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
# PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see <http://www.gnu.org/licenses/>.
"""Setup.py: build, distribute, clean."""

from __future__ import print_function, unicode_literals

import os
import shutil
import subprocess
import sys

from distutils.command import build
from distutils.spawn import find_executable

real_setup = None
real_clean = None
if sys.platform == 'linux2':
    try:
        import DistUtilsExtra.auto
        from DistUtilsExtra.auto import setup, clean_build_tree
        real_setup = setup
        real_clean = clean_build_tree
    except ImportError:
        sys.stderr.write('To build this program you need '
                         'https://launchpad.net/python-distutils-extra')
        sys.exit(1)
    assert DistUtilsExtra.auto.__version__ >= '2.18', \
        'needs DistUtilsExtra.auto >= 2.18'
else:
    from distutils.core import setup
    from distutils.command.clean import clean
    real_setup = setup
    real_clean = clean

POT_FILE = 'po/ubuntuone-client-data.pot'

CLEANFILES = [POT_FILE, 'MANIFEST']

ICON_SVG_FILE = 'ubuntuone-icons.svg'
ICON_RENDER_SIZES = ['16x16', '16x16@2x',
                     '24x24',
                     '32x32', '32x32@2x',
                     '48x48',
                     '128x128', '128x128@2x',
                     '256x256', '256x256@2x',
                     '512x512', '512x512@2x',
                     ]
ICNS_EMBED_SIZES = ['16x16', '16x16@2x',
                    '32x32', '32x32@2x',
                    '128x128', '128x128@2x',
                    '256x256', '256x256@2x',
                    '512x512', '512x512@2x',
                    ]
ICO_EMBED_SIZES = ['16x16',
                   '24x24',
                   '32x32',
                   '48x48',
                   '128x128',
                   '256x256',
                   ]
ICONSDIR = os.path.join(os.getcwd(), 'data', 'icons')


def touch(filename, timestamp=None):
    """Implement 'touch' so we can prod the mtime of the build directories."""
    f = os.open(filename, os.O_RDONLY)
    try:
        os.utime(filename, timestamp)
    finally:
        os.close(f)


class BuildPNG(build.build):
    """Class to generate the PNG icons from the big SVG."""

    description = 'build the PNG icons for use on Linux systems'

    def run(self):
        """Generate the icons."""
        if os.path.exists(ICONSDIR):
            dirtime = os.stat(ICONSDIR).st_mtime
            filetime = os.stat(ICON_SVG_FILE).st_mtime
            if (dirtime >= filetime):
                touch(ICONSDIR)
                return
        else:
            os.makedirs(ICONSDIR)

        icontool_render = find_executable('icontool-render')
        if icontool_render is None:
            sys.stderr.write('icontool is required to build icons.')
            return

        for size in ICON_RENDER_SIZES:
            args = [icontool_render, '-s', size, '-o', ICONSDIR, ICON_SVG_FILE]
            subprocess.call(args)

        touch(ICONSDIR)


class BuildICNS(BuildPNG):
    """Class to generate the ICNS icons from the PNGs."""

    description = 'build the ICNS file for use on Darwin systems'

    def run(self):
        """Generate the icons."""
        if sys.platform != 'darwin':
            raise OSError('Can only build high res icns files on darwin.')

        iconutil = find_executable('iconutil')
        if iconutil is None:
            sys.stderr.write('iconutil is required to build the icns file.')
            return

        icns_args = [iconutil, '-c', 'icns', 'ubuntuone.iconset']
        icns_dir = os.path.join(os.getcwd(), 'ubuntuone.iconset')
        try:
            os.makedirs(icns_dir)
        except OSError as e:
            if not os.path.isdir(icns_dir):
                raise e

        missing = []
        for size in ICNS_EMBED_SIZES:
            orig_file = os.path.join(ICONSDIR, size, 'apps', 'ubuntuone.png')
            link_file = os.path.join(icns_dir, 'icon_' + size + '.png')
            if os.path.exists(orig_file):
                if os.path.exists(link_file):
                    os.unlink(link_file)

                os.link(orig_file, link_file)
                icns_args.append(link_file)
            else:
                missing.append(link_file)
        if len(missing) > 0:
                raise IOError(
                    'Missing icon sizes needed for icns file.\n\t%s' %
                    '\n\t'.join(missing))

        subprocess.call(icns_args)
        shutil.rmtree(icns_dir)


class BuildICO(BuildPNG):
    """Class to generate the ICO file from the PNGs."""

    description = 'build the ICO file for use on Windows systems'

    def run(self):
        """Generate the icons."""
        BuildPNG.run(self)
        convert = find_executable('convert')
        if convert is None:
            sys.stderr.write('convert is required to build the ico file.')
            return

        convert_args = [convert]
        for size in ICO_EMBED_SIZES:
            orig_file = os.path.join(ICONSDIR, size, 'apps', 'ubuntuone.png')
            if os.path.exists(orig_file):
                convert_args.append(orig_file)
            else:
                raise IOError('Missing icon sizes needed for ico file.')

        convert_args.append('ubuntuone.ico')

        subprocess.call(convert_args)


class DataClean(real_clean):
    """Class to clean up after the build."""

    def run(self):
        """Clean up the built files."""
        for built_file in CLEANFILES:
            if os.path.exists(built_file):
                os.unlink(built_file)

        real_clean.run(self)


cmdclass = {
    'clean': DataClean,
    'build_png': BuildPNG,
    'build_icns': BuildICNS,
    'build_ico': BuildICO,
}

if sys.platform == 'linux2':
    data_files = [('share/apport/package-hooks',
                   ['apport/source_ubuntuone-client-data.py']),
                  ('/etc/apport/crashdb.conf.d',
                   ['apport/ubuntuone-client-data.conf']),
                  ]
else:
    data_files = []

real_setup(
    name='ubuntuone-client-data',
    version='14.04',
    license='GPL v3',
    author='Ubuntu One Developers',
    author_email='ubuntuone-users@lists.launchpad.net',
    description='Ubuntu One client data',
    long_description=('Client data used by the various Ubuntu One client'
                      'libraries and applications'),
    url='https://launchpad.net/ubuntuone-client-data',
    cmdclass=cmdclass,
    data_files=data_files,
)
