# -*- coding: ascii -*-
#
# Copyright 2007, 2008, 2009, 2010, 2011
# Andr\xe9 Malo or his licensors, as applicable
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
===================
 Data distribution
===================

This module provides tools to simplify data distribution.
"""
__author__ = u"Andr\xe9 Malo"
__docformat__ = "restructuredtext en"

from distutils import filelist as _filelist
import os as _os
import posixpath as _posixpath
import sys as _sys

from _setup import commands as _commands


def splitpath(path):
    """ Split a path """
    drive, path = '', _os.path.normpath(path)
    try:
        splitunc = _os.path.splitunc
    except AttributeError:
        pass
    else:
        drive, path = splitunc(path)
    if not drive:
        drive, path = _os.path.splitdrive(path)
    elems = []
    try:
        sep = _os.path.sep
    except AttributeError:
        sep = _os.path.join('1', '2')[1:-1]
    while 1:
        prefix, path = _os.path.split(path)
        elems.append(path)
        if prefix in ('', sep):
            drive = _os.path.join(drive, prefix)
            break
        path = prefix
    elems.reverse()
    return drive, elems


def finalizer(installer):
    """ Finalize install_data """
    data_files = []
    for item in installer.data_files:
        if not isinstance(item, Data):
            data_files.append(item)
            continue
        data_files.extend(item.flatten(installer))
    installer.data_files = data_files


class Data(object):
    """ File list container """

    def __init__(self, files, target=None, preserve=0, strip=0,
                 prefix=None):
        """ Initialization """
        self._files = files
        self._target = target
        self._preserve = preserve
        self._strip = strip
        self._prefix = prefix
        self.fixup_commands()

    def fixup_commands(self):
        pass

    def from_templates(cls, *templates, **kwargs):
        """ Initialize from template """
        files = _filelist.FileList()
        for tpl in templates:
            for line in tpl.split(';'):
                files.process_template_line(line.strip())
        files.sort()
        files.remove_duplicates()
        result = []
        for filename in files.files:
            _, elems = splitpath(filename)
            if '.svn' in elems or '.git' in elems:
                continue
            result.append(filename)
        return cls(result, **kwargs)
    from_templates = classmethod(from_templates)

    def flatten(self, installer):
        """ Flatten the file list to (target, file) tuples """
        # pylint: disable = W0613
        if self._prefix:
            _, prefix = splitpath(self._prefix)
            telems = prefix
        else:
            telems = []

        tmap = {}
        for fname in self._files:
            (_, name), target = splitpath(fname), telems
            if self._preserve:
                if self._strip:
                    name = name[max(0, min(self._strip, len(name) - 1)):]
                if len(name) > 1:
                    target = telems + name[:-1]
            tmap.setdefault(_posixpath.join(*target), []).append(fname)
        return tmap.items()


class Documentation(Data):
    """ Documentation container """

    def fixup_commands(self):
        _commands.add_option('install_data', 'without-docs',
            help_text='Do not install documentation files',
            inherit='install',
        )
        _commands.add_finalizer('install_data', 'documentation', finalizer)

    def flatten(self, installer):
        """ Check if docs should be installed at all """
        if installer.without_docs:
            return []
        return Data.flatten(self, installer)


class Manpages(Documentation):
    """ Manpages container """

    def dispatch(cls, files):
        """ Automatically dispatch manpages to their target directories """
        mpmap = {}
        for manpage in files:
            normalized = _os.path.normpath(manpage)
            _, ext = _os.path.splitext(normalized)
            if ext.startswith(_os.path.extsep):
                ext = ext[len(_os.path.extsep):]
            mpmap.setdefault(ext, []).append(manpage)
        return [cls(manpages, prefix=_posixpath.join(
            'share', 'man', 'man%s' % section,
        )) for section, manpages in mpmap.items()]
    dispatch = classmethod(dispatch)

    def flatten(self, installer):
        """ Check if manpages are suitable """
        if _sys.platform == 'win32':
            return []
        return Documentation.flatten(self, installer)
