#!/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.
#

""" 
<description>

@file:   apply_snapshot.py
@author: Kei Funagayama <kei.funagayama@hde.co.jp>
@copyright:    

<comment-ja>
指定したゲストOSにディスクを追加する

 使用方法: apply_snapshot.py [オプション]

  オプション:
    --version             プログラムのバージョンを表示
    -h, --help            使用方法を表示
    -n NAME, --name=NAME  ドメイン名を指定
    -i ID, --id=ID        スナップショットのIDを指定
</comment-ja>
<comment-en>
Attach a new disk device to the domain.

 usage: apply_snapshot.py [options]

  options:
    --version             show program's version number and exit
    -h, --help            show this help message and exit
    -n NAME, --name=NAME  Domain name
    -i ID, --id=ID        Snapshot serial ID
</comment-en>
"""

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

from ksscommand import KssCommand, KssCommandException, KssCommandOptException

try:
    import karesansui
    from karesansui.lib.const import VIRT_SNAPSHOT_DIR 
    from karesansui.lib.utils import is_writable
    from karesansui import __version__
    from karesansui.lib.utils import load_locale
    from karesansui.db.access.snapshot import findbyname, delete
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('-n', '--name', dest='name', help=_('Domain name'))
    optp.add_option('-i', '--id', dest='id', help=_('Snapshot serial ID'))
    return optp.parse_args()

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

    if not opts.id:
        raise KssCommandOptException('ERROR: -i or --id option is required.')

class DeleteSnapshot(KssCommand):

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

        target_filepath = "%s/%s/%s" % (VIRT_SNAPSHOT_DIR, opts.name, opts.id)

        # valid
        if os.path.isfile(target_filepath) is True:
            if is_writable(target_filepath) is False:
                raise KssCommandException(
                    'You do not have permission to delete. - %s' % target_filepath)

            # delete
            try:
                os.unlink(target_filepath)
                self.logger.info('Deleted files physically file. - path=%s' % target_filepath)
                print >>sys.stderr, 'Deleted files physically file. - path=%s' % target_filepath
                
            except IOError, e:
                self.logger.warn('Failed to delete the snapshot. - path=%s' % target_filepath)
                print >>sys.stderr, '[Warn] Failed to delete the snapshot. - path=%s' % target_filepath
        else:
            # Physical file -> skip
            self.logger.info('We skip the removal process of the physical file.')
            print >>sys.stderr, 'We skip the removal process of the physical file.'

        self.up_progress(10)
        # database
        snapshot = findbyname(self.kss_session, opts.id)
        if snapshot:
            delete(self.kss_session, snapshot)
            self.up_progress(40)
            self.kss_session.commit()
            self.logger.info('Deleted snapshot records. - %s' % opts.id)
            print >>sys.stderr, 'Deleted snapshot records. - %s' % opts.id
            
        else:
            # Database - Snapshot recode -> skip
            self.logger.info('We skip the removal process of the database recode.')
            print >>sys.stderr, 'We skip the removal process of the database recode.'

        return True
    
if __name__ == "__main__":
    target = DeleteSnapshot()
    sys.exit(target.run())
