"""Interactive helper used to create a setup.cfg file.

This script will generate a packaging configuration file by looking at
the current directory and asking the user questions.  It is intended to
be called as *pysetup create*.
"""

#  Original code by Sean Reifschneider <jafo@tummy.com>

#  Original TODO list:
#  Look for a license file and automatically add the category.
#  When a .c file is found during the walk, can we add it as an extension?
#  Ask if there is a maintainer different that the author
#  Ask for the platform (can we detect this via "import win32" or something?)
#  Ask for the dependencies.
#  Ask for the Requires-Dist
#  Ask for the Provides-Dist
#  Ask for a description
#  Detect scripts (not sure how.  #! outside of package?)

import os
import re
import imp
import sys
import glob
import shutil
import sysconfig
from hashlib import md5
from textwrap import dedent
from tokenize import detect_encoding
from configparser import RawConfigParser

from packaging import logger
# importing this with an underscore as it should be replaced by the
# dict form or another structures for all purposes
from packaging._trove import all_classifiers as _CLASSIFIERS_LIST
from packaging.version import is_valid_version

_FILENAME = 'setup.cfg'
_DEFAULT_CFG = '.pypkgcreate'  # FIXME use a section in user .pydistutils.cfg

_helptext = {
    'name': '''
The name of the project to be packaged, usually a single word composed
of lower-case characters such as "zope.interface", "sqlalchemy" or
"CherryPy".
''',
    'version': '''
Version number of the software, typically 2 or 3 numbers separated by
dots such as "1.0", "0.6b3", or "3.2.1".  "0.1.0" is recommended for
initial development.
''',
    'summary': '''
A one-line summary of what this project is or does, typically a sentence
80 characters or less in length.
''',
    'author': '''
The full name of the author (typically you).
''',
    'author_email': '''
Email address of the project author.
''',
    'do_classifier': '''
Trove classifiers are optional identifiers that allow you to specify the
intended audience by saying things like "Beta software with a text UI
for Linux under the PSF license".  However, this can be a somewhat
involved process.
''',
    'packages': '''
Python packages included in the project.
''',
    'modules': '''
Pure Python modules included in the project.
''',
    'extra_files': '''
You can provide extra files/dirs contained in your project.
It has to follow the template syntax. XXX add help here.
''',

    'home_page': '''
The home page for the project, typically a public Web page.
''',
    'trove_license': '''
Optionally you can specify a license.  Type a string that identifies a
common license, and then you can select a list of license specifiers.
''',
    'trove_generic': '''
Optionally, you can set other trove identifiers for things such as the
human language, programming language, user interface, etc.
''',
    'setup.py found': '''
The setup.py script will be executed to retrieve the metadata.
An interactive helper will be run if you answer "n",
''',
}

PROJECT_MATURITY = ['Development Status :: 1 - Planning',
                    'Development Status :: 2 - Pre-Alpha',
                    'Development Status :: 3 - Alpha',
                    'Development Status :: 4 - Beta',
                    'Development Status :: 5 - Production/Stable',
                    'Development Status :: 6 - Mature',
                    'Development Status :: 7 - Inactive']

# XXX everything needs docstrings and tests (both low-level tests of various
# methods and functional tests of running the script)


def load_setup():
    """run the setup script (i.e the setup.py file)

    This function load the setup file in all cases (even if it have already
    been loaded before, because we are monkey patching its setup function with
    a particular one"""
    with open("setup.py", "rb") as f:
        encoding, lines = detect_encoding(f.readline)
    with open("setup.py", encoding=encoding) as f:
        imp.load_module("setup", f, "setup.py", (".py", "r", imp.PY_SOURCE))


def ask_yn(question, default=None, helptext=None):
    question += ' (y/n)'
    while True:
        answer = ask(question, default, helptext, required=True)
        if answer and answer[0].lower() in ('y', 'n'):
            return answer[0].lower()

        logger.error('You must select "Y" or "N".')


# XXX use util.ask
# FIXME: if prompt ends with '?', don't add ':'


def ask(question, default=None, helptext=None, required=True,
        lengthy=False, multiline=False):
    prompt = '%s: ' % (question,)
    if default:
        prompt = '%s [%s]: ' % (question, default)
        if default and len(question) + len(default) > 70:
            prompt = '%s\n    [%s]: ' % (question, default)
    if lengthy or multiline:
        prompt += '\n   > '

    if not helptext:
        helptext = 'No additional help available.'

    helptext = helptext.strip("\n")

    while True:
        line = input(prompt).strip()
        if line == '?':
            print('=' * 70)
            print(helptext)
            print('=' * 70)
            continue
        if default and not line:
            return default
        if not line and required:
            print('*' * 70)
            print('This value cannot be empty.')
            print('===========================')
            if helptext:
                print(helptext)
            print('*' * 70)
            continue
        return line


def convert_yn_to_bool(yn, yes=True, no=False):
    """Convert a y/yes or n/no to a boolean value."""
    if yn.lower().startswith('y'):
        return yes
    else:
        return no


def _build_classifiers_dict(classifiers):
    d = {}
    for key in classifiers:
        subdict = d
        for subkey in key.split(' :: '):
            if subkey not in subdict:
                subdict[subkey] = {}
            subdict = subdict[subkey]
    return d

CLASSIFIERS = _build_classifiers_dict(_CLASSIFIERS_LIST)


def _build_licences(classifiers):
    res = []
    for index, item in enumerate(classifiers):
        if not item.startswith('License :: '):
            continue
        res.append((index, item.split(' :: ')[-1].lower()))
    return res

LICENCES = _build_licences(_CLASSIFIERS_LIST)


class MainProgram:
    """Make a project setup configuration file (setup.cfg)."""

    def __init__(self):
        self.configparser = None
        self.classifiers = set()
        self.data = {'name': '',
                     'version': '1.0.0',
                     'classifier': self.classifiers,
                     'packages': [],
                     'modules': [],
                     'platform': [],
                     'resources': [],
                     'extra_files': [],
                     'scripts': [],
                     }
        self._load_defaults()

    def __call__(self):
        setupcfg_defined = False
        if self.has_setup_py() and self._prompt_user_for_conversion():
            setupcfg_defined = self.convert_py_to_cfg()
        if not setupcfg_defined:
            self.define_cfg_values()
        self._write_cfg()

    def has_setup_py(self):
        """Test for the existence of a setup.py file."""
        return os.path.exists('setup.py')

    def define_cfg_values(self):
        self.inspect()
        self.query_user()

    def _lookup_option(self, key):
        if not self.configparser.has_option('DEFAULT', key):
            return None
        return self.configparser.get('DEFAULT', key)

    def _load_defaults(self):
        # Load default values from a user configuration file
        self.configparser = RawConfigParser()
        # TODO replace with section in distutils config file
        default_cfg = os.path.expanduser(os.path.join('~', _DEFAULT_CFG))
        self.configparser.read(default_cfg)
        self.data['author'] = self._lookup_option('author')
        self.data['author_email'] = self._lookup_option('author_email')

    def _prompt_user_for_conversion(self):
        # Prompt the user about whether they would like to use the setup.py
        # conversion utility to generate a setup.cfg or generate the setup.cfg
        # from scratch
        answer = ask_yn(('A legacy setup.py has been found.\n'
                         'Would you like to convert it to a setup.cfg?'),
                        default="y",
                        helptext=_helptext['setup.py found'])
        return convert_yn_to_bool(answer)

    def _dotted_packages(self, data):
        packages = sorted(data)
        modified_pkgs = []
        for pkg in packages:
            pkg = pkg.lstrip('./')
            pkg = pkg.replace('/', '.')
            modified_pkgs.append(pkg)
        return modified_pkgs

    def _write_cfg(self):
        if os.path.exists(_FILENAME):
            if os.path.exists('%s.old' % _FILENAME):
                message = ("ERROR: %(name)s.old backup exists, please check "
                           "that current %(name)s is correct and remove "
                           "%(name)s.old" % {'name': _FILENAME})
                logger.error(message)
                return
            shutil.move(_FILENAME, '%s.old' % _FILENAME)

        with open(_FILENAME, 'w', encoding='utf-8') as fp:
            fp.write('[metadata]\n')
            # TODO use metadata module instead of hard-coding field-specific
            # behavior here

            # simple string entries
            for name in ('name', 'version', 'summary', 'download_url'):
                fp.write('%s = %s\n' % (name, self.data.get(name, 'UNKNOWN')))

            # optional string entries
            if 'keywords' in self.data and self.data['keywords']:
                # XXX shoud use comma to separate, not space
                fp.write('keywords = %s\n' % ' '.join(self.data['keywords']))
            for name in ('home_page', 'author', 'author_email',
                         'maintainer', 'maintainer_email', 'description-file'):
                if name in self.data and self.data[name]:
                    fp.write('%s = %s\n' % (name, self.data[name]))
            if 'description' in self.data:
                fp.write(
                    'description = %s\n'
                    % '\n       |'.join(self.data['description'].split('\n')))

            # multiple use string entries
            for name in ('platform', 'supported-platform', 'classifier',
                         'requires-dist', 'provides-dist', 'obsoletes-dist',
                         'requires-external'):
                if not(name in self.data and self.data[name]):
                    continue
                fp.write('%s = ' % name)
                fp.write(''.join('    %s\n' % val
                                 for val in self.data[name]).lstrip())

            fp.write('\n[files]\n')

            for name in ('packages', 'modules', 'scripts', 'extra_files'):
                if not(name in self.data and self.data[name]):
                    continue
                fp.write('%s = %s\n'
                         % (name, '\n    '.join(self.data[name]).strip()))

            if self.data.get('package_data'):
                fp.write('package_data =\n')
                for pkg, spec in sorted(self.data['package_data'].items()):
                    # put one spec per line, indented under the package name
                    indent = ' ' * (len(pkg) + 7)
                    spec = ('\n' + indent).join(spec)
                    fp.write('    %s = %s\n' % (pkg, spec))
                fp.write('\n')

            if self.data.get('resources'):
                fp.write('resources =\n')
                for src, dest in self.data['resources']:
                    fp.write('    %s = %s\n' % (src, dest))
                fp.write('\n')

        os.chmod(_FILENAME, 0o644)
        logger.info('Wrote "%s".' % _FILENAME)

    def convert_py_to_cfg(self):
        """Generate a setup.cfg from an existing setup.py.

        It only exports the distutils metadata (setuptools specific metadata
        is not currently supported).
        """
        data = self.data

        def setup_mock(**attrs):
            """Mock the setup(**attrs) in order to retrieve metadata."""

            # TODO use config and metadata instead of Distribution
            from distutils.dist import Distribution
            dist = Distribution(attrs)
            dist.parse_config_files()

            # 1. retrieve metadata fields that are quite similar in
            # PEP 314 and PEP 345
            labels = (('name',) * 2,
                      ('version',) * 2,
                      ('author',) * 2,
                      ('author_email',) * 2,
                      ('maintainer',) * 2,
                      ('maintainer_email',) * 2,
                      ('description', 'summary'),
                      ('long_description', 'description'),
                      ('url', 'home_page'),
                      ('platforms', 'platform'),
                      ('provides', 'provides-dist'),
                      ('obsoletes', 'obsoletes-dist'),
                      ('requires', 'requires-dist'))

            get = lambda lab: getattr(dist.metadata, lab.replace('-', '_'))
            data.update((new, get(old)) for old, new in labels if get(old))

            # 2. retrieve data that requires special processing
            data['classifier'].update(dist.get_classifiers() or [])
            data['scripts'].extend(dist.scripts or [])
            data['packages'].extend(dist.packages or [])
            data['modules'].extend(dist.py_modules or [])
            # 2.1 data_files -> resources
            if dist.data_files:
                if (len(dist.data_files) < 2 or
                    isinstance(dist.data_files[1], str)):
                    dist.data_files = [('', dist.data_files)]
                # add tokens in the destination paths
                vars = {'distribution.name': data['name']}
                path_tokens = sysconfig.get_paths(vars=vars).items()
                # sort tokens to use the longest one first
                path_tokens = sorted(path_tokens, key=lambda x: len(x[1]))
                for dest, srcs in (dist.data_files or []):
                    dest = os.path.join(sys.prefix, dest)
                    dest = dest.replace(os.path.sep, '/')
                    for tok, path in path_tokens:
                        path = path.replace(os.path.sep, '/')
                        if not dest.startswith(path):
                            continue

                        dest = ('{%s}' % tok) + dest[len(path):]
                        files = [('/ '.join(src.rsplit('/', 1)), dest)
                                 for src in srcs]
                        data['resources'].extend(files)

            # 2.2 package_data
            data['package_data'] = dist.package_data.copy()

            # Use README file if its content is the desciption
            if "description" in data:
                ref = md5(re.sub('\s', '',
                                 self.data['description']).lower().encode())
                ref = ref.digest()
                for readme in glob.glob('README*'):
                    with open(readme, encoding='utf-8') as fp:
                        contents = fp.read()
                    contents = re.sub('\s', '', contents.lower()).encode()
                    val = md5(contents).digest()
                    if val == ref:
                        del data['description']
                        data['description-file'] = readme
                        break

        # apply monkey patch to distutils (v1) and setuptools (if needed)
        # (abort the feature if distutils v1 has been killed)
        try:
            from distutils import core
            core.setup  # make sure it's not d2 maskerading as d1
        except (ImportError, AttributeError):
            return
        saved_setups = [(core, core.setup)]
        core.setup = setup_mock
        try:
            import setuptools
        except ImportError:
            pass
        else:
            saved_setups.append((setuptools, setuptools.setup))
            setuptools.setup = setup_mock
        # get metadata by executing the setup.py with the patched setup(...)
        success = False  # for python < 2.4
        try:
            load_setup()
            success = True
        finally:  # revert monkey patches
            for patched_module, original_setup in saved_setups:
                patched_module.setup = original_setup
        if not self.data:
            raise ValueError('Unable to load metadata from setup.py')
        return success

    def inspect(self):
        """Inspect the current working diretory for a name and version.

        This information is harvested in where the directory is named
        like [name]-[version].
        """
        dir_name = os.path.basename(os.getcwd())
        self.data['name'] = dir_name
        match = re.match(r'(.*)-(\d.+)', dir_name)
        if match:
            self.data['name'] = match.group(1)
            self.data['version'] = match.group(2)
            # TODO needs testing!
            if not is_valid_version(self.data['version']):
                msg = "Invalid version discovered: %s" % self.data['version']
                raise ValueError(msg)

    def query_user(self):
        self.data['name'] = ask('Project name', self.data['name'],
              _helptext['name'])

        self.data['version'] = ask('Current version number',
              self.data.get('version'), _helptext['version'])
        self.data['summary'] = ask('Project description summary',
              self.data.get('summary'), _helptext['summary'],
              lengthy=True)
        self.data['author'] = ask('Author name',
              self.data.get('author'), _helptext['author'])
        self.data['author_email'] = ask('Author email address',
              self.data.get('author_email'), _helptext['author_email'])
        self.data['home_page'] = ask('Project home page',
              self.data.get('home_page'), _helptext['home_page'],
              required=False)

        if ask_yn('Do you want me to automatically build the file list '
              'with everything I can find in the current directory? '
              'If you say no, you will have to define them manually.') == 'y':
            self._find_files()
        else:
            while ask_yn('Do you want to add a single module?'
                        ' (you will be able to add full packages next)',
                    helptext=_helptext['modules']) == 'y':
                self._set_multi('Module name', 'modules')

            while ask_yn('Do you want to add a package?',
                    helptext=_helptext['packages']) == 'y':
                self._set_multi('Package name', 'packages')

            while ask_yn('Do you want to add an extra file?',
                        helptext=_helptext['extra_files']) == 'y':
                self._set_multi('Extra file/dir name', 'extra_files')

        if ask_yn('Do you want to set Trove classifiers?',
                  helptext=_helptext['do_classifier']) == 'y':
            self.set_classifier()

    def _find_files(self):
        # we are looking for python modules and packages,
        # other stuff are added as regular files
        pkgs = self.data['packages']
        modules = self.data['modules']
        extra_files = self.data['extra_files']

        def is_package(path):
            return os.path.exists(os.path.join(path, '__init__.py'))

        curdir = os.getcwd()
        scanned = []
        _pref = ['lib', 'include', 'dist', 'build', '.', '~']
        _suf = ['.pyc']

        def to_skip(path):
            path = relative(path)

            for pref in _pref:
                if path.startswith(pref):
                    return True

            for suf in _suf:
                if path.endswith(suf):
                    return True

            return False

        def relative(path):
            return path[len(curdir) + 1:]

        def dotted(path):
            res = relative(path).replace(os.path.sep, '.')
            if res.endswith('.py'):
                res = res[:-len('.py')]
            return res

        # first pass: packages
        for root, dirs, files in os.walk(curdir):
            if to_skip(root):
                continue
            for dir_ in sorted(dirs):
                if to_skip(dir_):
                    continue
                fullpath = os.path.join(root, dir_)
                dotted_name = dotted(fullpath)
                if is_package(fullpath) and dotted_name not in pkgs:
                    pkgs.append(dotted_name)
                    scanned.append(fullpath)

        # modules and extra files
        for root, dirs, files in os.walk(curdir):
            if to_skip(root):
                continue

            if any(root.startswith(path) for path in scanned):
                continue

            for file in sorted(files):
                fullpath = os.path.join(root, file)
                if to_skip(fullpath):
                    continue
                # single module?
                if os.path.splitext(file)[-1] == '.py':
                    modules.append(dotted(fullpath))
                else:
                    extra_files.append(relative(fullpath))

    def _set_multi(self, question, name):
        existing_values = self.data[name]
        value = ask(question, helptext=_helptext[name]).strip()
        if value not in existing_values:
            existing_values.append(value)

    def set_classifier(self):
        self.set_maturity_status(self.classifiers)
        self.set_license(self.classifiers)
        self.set_other_classifier(self.classifiers)

    def set_other_classifier(self, classifiers):
        if ask_yn('Do you want to set other trove identifiers?', 'n',
                  _helptext['trove_generic']) != 'y':
            return
        self.walk_classifiers(classifiers, [CLASSIFIERS], '')

    def walk_classifiers(self, classifiers, trovepath, desc):
        trove = trovepath[-1]

        if not trove:
            return

        for key in sorted(trove):
            if len(trove[key]) == 0:
                if ask_yn('Add "%s"' % desc[4:] + ' :: ' + key, 'n') == 'y':
                    classifiers.add(desc[4:] + ' :: ' + key)
                continue

            if ask_yn('Do you want to set items under\n   "%s" (%d sub-items)?'
                      % (key, len(trove[key])), 'n',
                      _helptext['trove_generic']) == 'y':
                self.walk_classifiers(classifiers, trovepath + [trove[key]],
                                      desc + ' :: ' + key)

    def set_license(self, classifiers):
        while True:
            license = ask('What license do you use?',
                          helptext=_helptext['trove_license'], required=False)
            if not license:
                return

            license_words = license.lower().split(' ')
            found_list = []

            for index, licence in LICENCES:
                for word in license_words:
                    if word in licence:
                        found_list.append(index)
                        break

            if len(found_list) == 0:
                logger.error('Could not find a matching license for "%s"' %
                             license)
                continue

            question = 'Matching licenses:\n\n'

            for index, list_index in enumerate(found_list):
                question += '   %s) %s\n' % (index + 1,
                                             _CLASSIFIERS_LIST[list_index])

            question += ('\nType the number of the license you wish to use or '
                         '? to try again:')
            choice = ask(question, required=False)

            if choice == '?':
                continue
            if choice == '':
                return

            try:
                index = found_list[int(choice) - 1]
            except ValueError:
                logger.error(
                    "Invalid selection, type a number from the list above.")

            classifiers.add(_CLASSIFIERS_LIST[index])

    def set_maturity_status(self, classifiers):
        maturity_name = lambda mat: mat.split('- ')[-1]
        maturity_question = '''\
            Please select the project status:

            %s

            Status''' % '\n'.join('%s - %s' % (i, maturity_name(n))
                                  for i, n in enumerate(PROJECT_MATURITY))
        while True:
            choice = ask(dedent(maturity_question), required=False)

            if choice:
                try:
                    choice = int(choice) - 1
                    key = PROJECT_MATURITY[choice]
                    classifiers.add(key)
                    return
                except (IndexError, ValueError):
                    logger.error(
                        "Invalid selection, type a single digit number.")


def main():
    """Main entry point."""
    program = MainProgram()
    # # uncomment when implemented
    # if not program.load_existing_setup_script():
    #     program.inspect_directory()
    #     program.query_user()
    #     program.update_config_file()
    # program.write_setup_script()
    # packaging.util.cfg_to_args()
    program()
