#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# This file is part of Karesansui.
#
# Copyright (C) 2009 HDE, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#

import os
import os.path
import sys
import signal
import logging
from optparse import OptionParser

from ksscommand import KssCommand, KssCommandException, KssCommandOptException

import __cmd__

try:
    import karesansui
    from karesansui import __version__
    from karesansui.lib.virt.virt import KaresansuiVirtConnection
    from karesansui.lib.utils import load_locale
    from karesansui.lib.const import VIRT_DISK_IMAGE_DIR
except ImportError:
    print >>sys.stderr, "[Error] karesansui package was not found."
    sys.exit(1)

_ = load_locale()

usage = '%prog [options]'

def getopts():
    optp = OptionParser(usage=usage, version=__version__)
    optp.add_option('-s', '--src-name', dest='src_name', help=_('Source domain name'))
    optp.add_option('-d', '--dest-name', dest='name', help=_('Destination domain name'))
    optp.add_option('-v', '--vnc-port', dest='vnc_port', help=_('VNC port number'), default=None)
    optp.add_option('-u', '--uuid', dest='uuid', help=_('UUID'), default=None)
    optp.add_option('-a', '--mac', dest='mac', help=_('MAC address'), default=None)
    return optp.parse_args()

def chkopts(opts):
    if not opts.name:
        raise KssCommandOptException('ERROR: -d or --dest-name option is required.')
    if not opts.src_name:
        raise KssCommandOptException('ERROR: -s or --src-name option is required.')

class ReplicateGuest(KssCommand):

    def process(self):
        (opts, args) = getopts()
        chkopts(opts)
        self.up_progress(10)

        self.src_disk = VIRT_DISK_IMAGE_DIR + "/"+ opts.src_name +".img"
        self.dest_disk = VIRT_DISK_IMAGE_DIR + "/"+ opts.name +".img"

        if os.path.isfile(self.src_disk) is False:
            raise KssCommandException(
                'source disk image is not found. - src=%s' % (self.src_disk))

        if os.path.isfile(self.dest_disk) is True:
            raise KssCommandException(
                'destination disk image already exists. - dest=%s' % (self.dest_disk))

        self.up_progress(10)

        conn = KaresansuiVirtConnection(readonly=False)
        try:
            try:
                active_guests = conn.list_active_guest()
                inactive_guests = conn.list_inactive_guest()
                # source guestos
                if not (opts.src_name in active_guests or opts.src_name in inactive_guests):
                    raise KssCommandException(
                        "Unable to get the source guest OS. - src_name=%s" % opts.src_name)

                if (opts.name in active_guests or opts.name in inactive_guests):
                    raise KssCommandException(
                        "Destination Guest OS is already there. - dest_name=%s" % opts.name)

                self.up_progress(10)
                conn.replicate_guest(opts.name, opts.src_name, opts.mac, opts.uuid, opts.vnc_port)
                self.up_progress(40)
            except:
                self.logger.error('Failed to replicate guest. - src=%s dom=%s' % (opts.src_name,opts.name))
                raise
        finally:
            conn.close()

        conn1 = KaresansuiVirtConnection(readonly=False)
        try:
            self.up_progress(10)
            active_guests = conn1.list_active_guest()
            inactive_guests = conn1.list_inactive_guest()
            if opts.name in active_guests or opts.name in inactive_guests:
                self.logger.info('Replicated guest. - src=%s dom=%s' % (opts.src_name,opts.name))
                print >>sys.stderr, _('Replicated guest. - src=%s dom=%s') % (opts.src_name,opts.name)
                return True
            else:
                raise KssCommandException(
                    'Replicate guest not found. - src=%s dom=%s' % (opts.src_name,opts.name))
        finally:
            conn1.close()

        return True

    def sigusr1_handler(self, signum, frame):
        if os.path.exists(self.src_disk) and os.path.exists(self.dest_disk):
            s_size = os.path.getsize(self.src_disk)
            d_size = os.path.getsize(self.dest_disk)
            print int(d_size*100/s_size)

    def sigint_handler(self, signum, frame):
        if os.path.exists(self.dest_disk):
            os.unlink(self.dest_disk)
        self.logger.error('Aborted by user request.')
        print >> sys.stderr, _("Aborted by user request.")
        raise ""

if __name__ == "__main__":
    target = ReplicateGuest()
    #signal.signal(signal.SIGUSR1, target.sigusr1_handler)
    #signal.signal(signal.SIGINT,  target.sigint_handler)
    sys.exit(target.run())
