#!/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_TIMEOUT,
    DEFAULT_EXPECT_DELAY,
    DEFAULT_EXPECT_ENCODING,
    DEFAULT_RSYNC_OPTIONS
)
from tomahawk.log import create_logger
from tomahawk.main import RsyncMain
from tomahawk.utils import 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(
        '-t', '--timeout', metavar='SECONDS', type=int, default=DEFAULT_TIMEOUT,
        help='Specify expect timeout in seconds. (default: %d)' % (DEFAULT_TIMEOUT)
    )
    p.add_argument(
        '--expect-timeout', metavar='SECONDS', type=int,
        help='Duplicated. Use --timeout'
    )
    p.add_argument(
        '--expect-encoding', metavar='ENCODING', default=DEFAULT_EXPECT_ENCODING,
        help='Specify expect encoding for password prompt. (default: %s)' % (DEFAULT_EXPECT_ENCODING)
    )
    p.add_argument(
        '-d', '--delay', type=int, default=0,
        help='Command delay time in seconds. (default: 0)'
    )
    p.add_argument(
        '--expect-delay', type=float, default=DEFAULT_EXPECT_DELAY,
        help='Expect delay time in seconds. (default: 0.05)'
    )
    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__':
    try:
        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.__dict__,
            arg_parser,
        )
        
        if options.profile:
            file = '%s.prof.%d' % (os.path.basename(__file__), os.getpid())
            cProfile = __import__('cProfile')
            pstats = __import__('pstats')
            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())
    except KeyboardInterrupt:
        print
        print("Keyboard interrupt.")
