

from __future__ import absolute_import
from __future__ import division

from vdsm import virtsysprep
from vdsm.common import properties
from vdsm.virt.utils import prepared
import vdsm.virt.jobs


class ImagePreparingError(Exception):
    ''' Error preparing image '''


class ImageTearingDownError(Exception):
    ''' Error tearing down image '''


class Job(vdsm.virt.jobs.Job):

    def __init__(self, job_id, sp_id, images, irs):
        super(Job, self).__init__(job_id, 'seal_vm')
        self._images = [
            SealImageInfo(image, sp_id, irs)
            for image in images
        ]

    def _run(self):
        with prepared(self._images):
            vol_paths = [image_info.path for image_info in self._images]
            virtsysprep.sysprep(vol_paths)


class SealImageInfo(properties.Owner):
    sd_id = properties.UUID(required=True)
    img_id = properties.UUID(required=True)
    vol_id = properties.UUID(required=True)

    def __init__(self, params, sp_id, irs):
        self.sd_id = params.get('sd_id')
        self.img_id = params.get('img_id')
        self.vol_id = params.get('vol_id')
        self._sp_id = sp_id
        self._irs = irs
        self._path = None

    @property
    def path(self):
        return self._path

    def prepare(self):
        res = self._irs.prepareImage(self.sd_id,
                                     self._sp_id,
                                     self.img_id,
                                     self.vol_id,
                                     allowIllegal=True)
        if res['status']['code']:
            raise ImagePreparingError("Cannot prepare image %s: %s" %
                                      (self, res['status']['message']))

        self._path = res['path']

    def teardown(self):
        res = self._irs.teardownImage(self.sd_id,
                                      self._sp_id,
                                      self.img_id)
        if res['status']['code']:
            raise ImageTearingDownError("Cannot tear down image %s: %s" %
                                        (self, res['status']['message']))

    def __repr__(self):
        return ("<%s sd_id=%s img_id=%s vol_id=%s at 0x%s>" %
                (self.__class__.__name__, self.sd_id, self.img_id, self.vol_id,
                 id(self)))
