from __future__ import print_function
from argparse import ArgumentParser
import os
from subprocess import CalledProcessError
import sys
import textwrap

from ruamel import yaml

from borgmatic import borg
from borgmatic.config import convert, generate, legacy, validate


DEFAULT_SOURCE_CONFIG_FILENAME = '/etc/borgmatic/config'
DEFAULT_SOURCE_EXCLUDES_FILENAME = '/etc/borgmatic/excludes'
DEFAULT_DESTINATION_CONFIG_FILENAME = '/etc/borgmatic/config.yaml'


def parse_arguments(*arguments):
    '''
    Given command-line arguments with which this script was invoked, parse the arguments and return
    them as an ArgumentParser instance.
    '''
    parser = ArgumentParser(
        description='''
            Convert legacy INI-style borgmatic configuration and excludes files to a single YAML
            configuration file. Note that this replaces any comments from the source files.
        '''
    )
    parser.add_argument(
        '-s', '--source-config',
        dest='source_config_filename',
        default=DEFAULT_SOURCE_CONFIG_FILENAME,
        help='Source INI-style configuration filename. Default: {}'.format(DEFAULT_SOURCE_CONFIG_FILENAME),
    )
    parser.add_argument(
        '-e', '--source-excludes',
        dest='source_excludes_filename',
        default=DEFAULT_SOURCE_EXCLUDES_FILENAME if os.path.exists(DEFAULT_SOURCE_EXCLUDES_FILENAME) else None,
        help='Excludes filename',
    )
    parser.add_argument(
        '-d', '--destination-config',
        dest='destination_config_filename',
        default=DEFAULT_DESTINATION_CONFIG_FILENAME,
        help='Destination YAML configuration filename. Default: {}'.format(DEFAULT_DESTINATION_CONFIG_FILENAME),
    )

    return parser.parse_args(arguments)


TEXT_WRAP_CHARACTERS = 80


def display_result(args):  # pragma: no cover
    result_lines = textwrap.wrap(
        'Your borgmatic configuration has been upgraded. Please review the result in {}.'.format(
            args.destination_config_filename
        ),
        TEXT_WRAP_CHARACTERS,
    )
    
    delete_lines = textwrap.wrap(
        'Once you are satisfied, you can safely delete {}{}.'.format(
            args.source_config_filename,
            ' and {}'.format(args.source_excludes_filename) if args.source_excludes_filename else '',
        ),
        TEXT_WRAP_CHARACTERS,
    )

    print('\n'.join(result_lines))
    print()
    print('\n'.join(delete_lines))


def main():  # pragma: no cover
    try:
        args = parse_arguments(*sys.argv[1:])
        schema = yaml.round_trip_load(open(validate.schema_filename()).read())
        source_config = legacy.parse_configuration(args.source_config_filename, legacy.CONFIG_FORMAT)
        source_config_file_mode = os.stat(args.source_config_filename).st_mode
        source_excludes = (
            open(args.source_excludes_filename).read().splitlines()
            if args.source_excludes_filename
            else []
        )

        destination_config = convert.convert_legacy_parsed_config(source_config, source_excludes, schema)

        generate.write_configuration(
            args.destination_config_filename,
            destination_config,
            mode=source_config_file_mode,
        )

        display_result(args)
    except (ValueError, OSError) as error:
        print(error, file=sys.stderr)
        sys.exit(1)
