#! /usr/bin/env python

"""Migrate a post-receive-email configuration to be usable with git_multimail.py.

See README.migrate-from-post-receive-email for more information.

"""

import sys
import optparse

from git_multimail import CommandError
from git_multimail import Config
from git_multimail import read_output


OLD_NAMES = [
    'mailinglist',
    'announcelist',
    'envelopesender',
    'emailprefix',
    'showrev',
    'emailmaxlines',
    'diffopts',
    'scancommitforcc',
    ]

NEW_NAMES = [
    'environment',
    'reponame',
    'mailinglist',
    'refchangelist',
    'commitlist',
    'announcelist',
    'announceshortlog',
    'envelopesender',
    'administrator',
    'emailprefix',
    'emailmaxlines',
    'diffopts',
    'emaildomain',
    'scancommitforcc',
    ]


INFO = """\

SUCCESS!

Your post-receive-email configuration has been converted to
git-multimail format.  Please see README and
README.migrate-from-post-receive-email to learn about other
git-multimail configuration possibilities.

For example, git-multimail has the following new options with no
equivalent in post-receive-email.  You might want to read about them
to see if they would be useful in your situation:

"""


def _check_old_config_exists(old):
    """Check that at least one old configuration value is set."""

    for name in OLD_NAMES:
        if name in old:
            return True

    return False


def _check_new_config_clear(new):
    """Check that none of the new configuration names are set."""

    retval = True
    for name in NEW_NAMES:
        if name in new:
            if retval:
                sys.stderr.write('INFO: The following configuration values already exist:\n\n')
            sys.stderr.write('    "%s.%s"\n' % (new.section, name))
            retval = False

    return retval


def erase_values(config, names):
    for name in names:
        if name in config:
            try:
                sys.stderr.write('...unsetting "%s.%s"\n' % (config.section, name))
                config.unset_all(name)
            except CommandError:
                sys.stderr.write(
                    '\nWARNING: could not unset "%s.%s".  '
                    'Perhaps it is not set at the --local level?\n\n'
                    % (config.section, name)
                    )


def is_section_empty(section, local):
    """Return True iff the specified configuration section is empty.

    Iff local is True, use the --local option when invoking 'git
    config'."""

    if local:
        local_option = ['--local']
    else:
        local_option = []

    try:
        read_output(
            ['git', 'config'] +
            local_option +
            ['--get-regexp', '^%s\.' % (section,)]
            )
    except CommandError:
        t, e, traceback = sys.exc_info()
        if e.retcode == 1:
            # This means that no settings were found.
            return True
        else:
            raise
    else:
        return False


def remove_section_if_empty(section):
    """If the specified configuration section is empty, delete it."""

    try:
        empty = is_section_empty(section, local=True)
    except CommandError:
        # Older versions of git do not support the --local option, so
        # if the first attempt fails, try without --local.
        try:
            empty = is_section_empty(section, local=False)
        except CommandError:
            sys.stderr.write(
                '\nINFO: If configuration section "%s.*" is empty, you might want '
                'to delete it.\n\n'
                % (section,)
                )
            return

    if empty:
        sys.stderr.write('...removing section "%s.*"\n' % (section,))
        read_output(['git', 'config', '--remove-section', section])
    else:
        sys.stderr.write(
            '\nINFO: Configuration section "%s.*" still has contents.  '
            'It will not be deleted.\n\n'
            % (section,)
            )


def migrate_config(strict=False, retain=False, overwrite=False):
    old = Config('hooks')
    new = Config('multimailhook')
    if not _check_old_config_exists(old):
        sys.exit(
            'Your repository has no post-receive-email configuration.  '
            'Nothing to do.'
            )
    if not _check_new_config_clear(new):
        if overwrite:
            sys.stderr.write('\nWARNING: Erasing the above values...\n\n')
            erase_values(new, NEW_NAMES)
        else:
            sys.exit(
                '\nERROR: Refusing to overwrite existing values.  Use the --overwrite\n'
                'option to continue anyway.'
                )

    name = 'showrev'
    if name in old:
        msg = 'git-multimail does not support "%s.%s"' % (old.section, name,)
        if strict:
            sys.exit(
                'ERROR: %s.\n'
                'Please unset that value then try again, or run without --strict.'
                % (msg,)
                )
        else:
            sys.stderr.write('\nWARNING: %s (ignoring).\n\n' % (msg,))

    for name in ['mailinglist', 'announcelist']:
        if name in old:
            sys.stderr.write(
                '...copying "%s.%s" to "%s.%s"\n' % (old.section, name, new.section, name)
                )
            old_recipients = old.get_all(name, default=None)
            old_recipients = ', '.join(o.strip() for o in old_recipients)
            new.set_recipients(name, old_recipients)

    if strict:
        sys.stderr.write(
            '...setting "%s.commitlist" to the empty string\n' % (new.section,)
            )
        new.set_recipients('commitlist', '')
        sys.stderr.write(
            '...setting "%s.announceshortlog" to "true"\n' % (new.section,)
            )
        new.set('announceshortlog', 'true')

    for name in ['envelopesender', 'emailmaxlines', 'diffopts', 'scancommitforcc']:
        if name in old:
            sys.stderr.write(
                '...copying "%s.%s" to "%s.%s"\n' % (old.section, name, new.section, name)
                )
            new.set(name, old.get(name))

    name = 'emailprefix'
    if name in old:
        sys.stderr.write(
            '...copying "%s.%s" to "%s.%s"\n' % (old.section, name, new.section, name)
            )
        new.set(name, old.get(name))
    elif strict:
        sys.stderr.write(
            '...setting "%s.%s" to "[SCM]" to preserve old subject lines\n'
            % (new.section, name)
            )
        new.set(name, '[SCM]')

    if not retain:
        erase_values(old, OLD_NAMES)
        remove_section_if_empty(old.section)

    sys.stderr.write(INFO)
    for name in NEW_NAMES:
        if name not in OLD_NAMES:
            sys.stderr.write('    "%s.%s"\n' % (new.section, name,))
    sys.stderr.write('\n')


def main(args):
    parser = optparse.OptionParser(
        description=__doc__,
        usage='%prog [OPTIONS]',
        )

    parser.add_option(
        '--strict', action='store_true', default=False,
        help=(
            'Slavishly configure git-multimail as closely as possible to '
            'the post-receive-email configuration.  Default is to turn '
            'on some new features that have no equivalent in post-receive-email.'
            ),
        )
    parser.add_option(
        '--retain', action='store_true', default=False,
        help=(
            'Retain the post-receive-email configuration values.  '
            'Default is to delete them after the new values are set.'
            ),
        )
    parser.add_option(
        '--overwrite', action='store_true', default=False,
        help=(
            'Overwrite any existing git-multimail configuration settings.  '
            'Default is to abort if such settings already exist.'
            ),
        )

    (options, args) = parser.parse_args(args)

    if args:
        parser.error('Unexpected arguments: %s' % (' '.join(args),))

    migrate_config(strict=options.strict, retain=options.retain, overwrite=options.overwrite)


main(sys.argv[1:])
