#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import signal
import sys
import tomahawk_bootstrap

parent, bin_dir = tomahawk_bootstrap.set_lib_path(__file__)

import argparse
from tomahawk.command_line import RsyncContext
from tomahawk.constants import (
    VERSION,
    DEFAULT_EXPECT_TIMEOUT,
    DEFAULT_RSYNC_OPTIONS
)
from tomahawk.log import create_logger
from tomahawk.main import RsyncMain
from tomahawk.utils import shutdown_by_signal

# Trap SIGINT(Ctrl-C) to quit executing a command
signal.signal(signal.SIGINT, shutdown_by_signal)

def create_argument_parser():
    p = argparse.ArgumentParser(
        prog = os.path.basename(__file__),
        description = 'A simple rsync executor for many hosts.',
        conflict_handler = 'resolve'
    )

    p.add_argument(
        'source', metavar='source', help='source',
    )
    p.add_argument(
        'destination', metavar='destination', help='destination',
    )
    p.add_argument(
        '-h', '--hosts', metavar='HOST',
        help='host names for rsync.',
    )
    p.add_argument(
        '-f', '--hosts-files', metavar='HOST_FILE',
        help='hosts files listed host names.'
    )
    p.add_argument(
        '-u', '--rsync-user', help='rsync user.'
    )
    p.add_argument(
        '-o', '--rsync-options', default=DEFAULT_RSYNC_OPTIONS,
        help='rsync options. (default: "-avz")'
    )
    p.add_argument(
        '-m', '--mirror-mode',
        help='"push" or "pull". "pull" means copy files remote -> local (default: "push")'
    )
#    p.add_argument(
#        '-a', '--append-host-suffix', action='store_true', default=True,
#        help='Append host name to destination file/dir (only when "--mirror-mode=pull").'
#    )
    p.add_argument(
        '-c', '--continue-on-error', action='store_true', default=None,
        help='Command exectuion continues whatever any errors.'
    )
    p.add_argument(
        '-p', '--parallel', metavar='NUM', type=int, default=1,
        help='A number for parallel command execution. (default: 1)'
    )
    p.add_argument(
        '-l', '--prompt-login-password', action='store_true',
        help='Prompt a password for ssh authentication.'
    )
    p.add_argument(
        '--expect-timeout', metavar='SECONDS', type=int, default=DEFAULT_EXPECT_TIMEOUT,
        help='Specify expect timeout in seconds. (default: %d)' % (DEFAULT_EXPECT_TIMEOUT)
    )
    p.add_argument(
        '-d', '--delay', type=int, default=0,
        help='Command delay time in seconds. (default: 0)'
    )
    p.add_argument(
        '-D', '--debug', action='store_true', default=False,
        help='Debug output enabled.',
    )
    p.add_argument(
        '--profile', action='store_true', help='enable profiling.'
    )
    p.add_argument(
        '--version', action='version', version='%(prog)s ' + VERSION
    )
    return p

if __name__ == '__main__':
    arg_parser = create_argument_parser()
    options = arg_parser.parse_args()
    log = create_logger(options.debug)
    log.debug('options = ' + str(options))
    log.debug('source = ' + str(options.source))
    log.debug('destination = ' + str(options.destination))

    context = RsyncContext(
        bin_dir,
        options.source,
        options.destination,
        options,
        arg_parser,
    )

    if options.profile:
        # TODO: dynamically import
        import cProfile
        import pstats
        file = '%s.prof.%d' % (os.path.basename(__file__), os.getpid())
        prof = cProfile.run("RsyncMain(context, log).run()", file)
        p = pstats.Stats(file)
        p.strip_dirs()
        p.sort_stats('time', 'calls')
        p.print_stats()
    else:
        sys.exit(RsyncMain(context, log).run())
