import argparse
import difflib
import os.path
import sys
from tempfile import NamedTemporaryFile
from .engine import SedgeEngine, SedgeException, ConfigOutput
from .keylib import KeyLibrary


def ask_overwrite(fname):
    print(
        "WARNING: `%s' already exists and was not generated by sedge." % fname,
        file=sys.stderr)
    confirm = input("Enter `yes' to overwite: ")
    return confirm == 'yes'


def check_or_confirm_overwrite(fname):
    "returns True if OK to proceed, False otherwise"
    try:
        with open(fname) as fd:
            header = next(fd)
            if header.find(':sedge:') == -1:
                okay = ask_overwrite(fname)
                if okay:
                    backup_file = fname + '.pre-sedge'
                    os.rename(fname, backup_file)
                    print("your previous SSH configuration file has been renamed to:\n%s" % (backup_file), file=sys.stderr)
    except OSError:
        pass
    except StopIteration:
        pass
    return True


def diff_config_changes(before, after):
    def get_data(f):
        with open(f) as fd:
            return fd.read().splitlines(True)
    a = get_data(before)
    b = get_data(after)
    diff_lines = list(difflib.unified_diff(a, b))
    if not diff_lines:
        print("no changes.", file=sys.stderr)
    else:
        print('configuration changes:', file=sys.stderr)
        print(''.join(diff_lines), file=sys.stderr)


def process(args):
    def write_to(out):
        config.output(out)
    library = KeyLibrary(args.key_directory, verbose=args.verbose)
    library.scan()
    with open(args.config_file) as fd:
        config = SedgeEngine(library, fd)
    if args.output_file == '-':
        write_to(ConfigOutput(sys.stdout))
        return
    if not check_or_confirm_overwrite(args.output_file):
        print("Aborting.", file=sys.stderr)
        sys.exit(1)

    tmpf = NamedTemporaryFile(mode='w', dir=os.path.dirname(args.output_file), delete=False)
    try:
        tmpf.file.write('''\
# :sedge:
#
# this configuration generated from `sedge' file:
# %s
#
# do not edit this file manually, edit the source file and re-run `sedge'
#

''' % (args.output_file))
        write_to(ConfigOutput(tmpf.file))
        tmpf.close()
        if args.verbose:
            diff_config_changes(args.output_file, tmpf.name)
        os.rename(tmpf.name, args.output_file)
    except:
        os.unlink(tmpf.name)
        raise


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-k', '--key_directory',
        default=os.path.expanduser('~/.ssh'),
        type=str,
        help='directory to scan for SSH keys')
    parser.add_argument(
        '-v', '--verbose',
        action='store_true',
        help='verbose output (including key fingerprints)')
    parser.add_argument(
        '--version', action='store_true',
        help='print version and exit')
    parser.add_argument(
        '-c', '--config-file',
        default=os.path.expanduser('~/.sedge/config'),
        nargs='?')
    parser.add_argument(
        '-o', '--output-file',
        default=os.path.expanduser('~/.ssh/config'),
        nargs='?')
    args = parser.parse_args()
    if args.version:
        import pkg_resources
        version = pkg_resources.require("sedge")[0].version
        print('sedge, version %s' % (version))
        sys.exit(0)
    try:
        process(args)
    except SedgeException as e:
        print('Error: %s' % (e), file=sys.stderr)
