#!/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 sys
import logging
import traceback
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.db.access.machine import findby1uniquekey, deleteby1uniquekey
    from karesansui.db.access.machine2jobgroup import deleteby1machine
    from karesansui.lib.const import VIRT_XEN_CONFIG_DIR, VIRT_XML_CONFIG_DIR, \
         VIRT_DISK_IMAGE_DIR, VIRT_SNAPSHOT_DIR, VIRT_DISK_DIR

except ImportError, e:
    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('-n', '--name', dest='name', help=_('Domain Name'))
    return optp.parse_args()

def chkopts(opts):
    if not opts.name:
        raise KssCommandOptException('ERROR: -n or --name option is required.')

class DeleteGuest(KssCommand):

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

        conn = KaresansuiVirtConnection(readonly=False)
        try:
            uuid = conn.domname_to_uuid(opts.name)
            
            # physical
            try:
                conn.set_domain_name(opts.name)
                conn.delete_guest()
                self.up_progress(20)
            except Exception, e:
                print >>sys.stderr, '[Warn] Failed to delete the guest OS physical. - dom=%s - detail : %s' \
                      % (opts.name, str(e.args))
                self.logger.warn('Failed to delete the guest OS physical. - dom=%s - detail : %s' \
                                 % (opts.name, str(e.args)))

            # Check the presence of residual files
            try:
                self.up_progress(10)
                # /etc
                xen_config = VIRT_XEN_CONFIG_DIR+opts.name
                if os.path.isfile(xen_config) is True:
                    os.remove(xen_config)
                    self.logger.info("physical xen config remove. - path=%s" % xen_config)

                self.up_progress(5)
                xml_config = '%s/%s.xml' % (VIRT_XML_CONFIG_DIR, opts.name)
                if os.path.isfile(xml_config) is True:
                    os.remove(xml_config)
                    self.logger.info("physical xml config remove. - path=%s" % xml_config)

                self.up_progress(5)
                disk_image = '%s/%s.img' % (VIRT_DISK_IMAGE_DIR, opts.name)
                if os.path.isfile(disk_image) is True:
                    os.remove(disk_image)
                    self.logger.info("physical disk image remove. - path=%s" % disk_image)

                self.up_progress(5)
                if 0 < len(opts.name.split()): # double check
                    snapshot_dir = '%s/%s' % (VIRT_SNAPSHOT_DIR, opts.name)
                    if os.path.isdir(snapshot_dir) is True:
                        
                        for root, dirs, files in os.walk(snapshot_dir):
                            for fname in files:
                                file_path = os.path.join(root, fname)
                                os.remove(file_path)
                                self.logger.info("physical snapshots file remove. - file=%s" % file_path)
                                
                        os.removedirs(snapshot_dir)
                        self.logger.info("physical snapshots directory remove. - dir=%s" % snapshot_dir)

                self.up_progress(5)
                if 0 < len(opts.name.split()): # double check
                    disk_dir = '%s/%s' % (VIRT_DISK_DIR, opts.name)
                    if os.path.isdir(disk_dir) is True:
                        
                        for root, dirs, files in os.walk(disk_dir):
                            for fname in files:
                                file_path = os.path.join(root, fname)
                                os.remove(file_path)
                                self.logger.info("physical disk file remove. - file=%s" % file_path)
                                
                        os.removedirs(disk_dir)
                        self.logger.info("physical disk directory remove. - dir=%s" % disk_dir)

                self.up_progress(5)

            except Exception, e:
                print >>sys.stderr, '[Warn] Failed to remove the residual file.. - dom=%s - detail : %s' \
                      % (opts.name, str(e.args))
                self.logger.warn('Failed to remove the residual file.. - dom=%s - detail : %s' \
                                  % (opts.name, str(e.args)))

            # database
            try:
                if uuid == '':
                    raise KssCommandException('UUID did not get that.')
                
                # rollback - machine
                self.up_progress(5)
                deleteby1uniquekey(self.kss_session, uuid)
                self.up_progress(5)
            except KssCommandException, e:
                print >>sys.stderr, '[Warn] Failed to delete the guest OS database. - dom=%s - detail : %s' \
                      % (opts.name, str(e.args))
                self.logger.warn('Failed to delete the guest OS database. - dom=%s - detail : %s' \
                                 % (opts.name, str(e.args)))

            self.logger.info('deleted guestos. - dom=%s' % opts.name)
            print >>sys.stderr, 'deleted guestos. - dom=%s' % opts.name
            return True

        finally:
            conn.close()

if __name__ == "__main__":
    target = DeleteGuest()
    sys.exit(target.run())
