from constants import *
from exceptions import *
from config import Config
from origin import Origin
from task import Task
from event import Event
from core_snapshot import CoreSnapshot
from create_snapshot import CreateSnapshot
from remove_snapshot import RemoveSnapshot
from restore_object import RestoreObject
from move_volume import MoveVolume
import os
import time
import uuid
import logging

logger = logging.getLogger(APP_NAME)

class CoreVolume(Config):
    bool_options = ['email_ssl']
    int_options = ['snapshot_limit', 'bandwidth_limit']
    float_options = ['min_free_space', 'max_prune']
    path_options = ['excludes', 'source_path']
    str_options = ['id', 'name', 'schedule', 'email', 'email_host',
        'email_user', 'email_pass', 'ssh_host', 'ssh_user', 'ssh_pass',
        'ssh_key']
    list_options = ['excludes']
    SnapshotClass = CoreSnapshot

    def __init__(self, client, path, create=False):
        try:
            config_path = os.path.join(path, CONF_FILENAME)
        except AttributeError:
            logger.error('Failed to join volume config path. %r' % {
                'volume_id': self.id,
            })
            raise
        Config.__init__(self, config_path)

        self.client = client
        self.orig_path = path
        self.orig_source_path = self.source_path
        self.path = path

        if not self.id:
            if create:
                self.id = uuid.uuid4().hex
                logger.debug('Setting new volume uuid. %r' % {
                    'volume_id': self.id,
                })
                self.commit()
            else:
                raise IOError('Volume doesnt exists')

    def __getattr__(self, name):
        if name == 'snapshots':
            self.load_snapshots()
        elif name == 'log_dir':
            return self._get_log_dir()
        return Config.__getattr__(self, name)

    def get_snapshot(self, id):
        for snapshot in self.snapshots:
            if snapshot.id == id:
                return snapshot

    def get_failed_snapshots(self):
        snapshots = []
        for snapshot in self.snapshots:
            if snapshot.state == FAILED:
                snapshots.append(snapshot)
        return snapshots

    def get_snapshots(self):
        snapshots = []
        for snapshot in self.snapshots:
            if snapshot.state in [WARNING, COMPLETE]:
                snapshots.append(snapshot)
        return snapshots

    def get_snapshot_count(self):
        count = 0
        for snapshot in self.snapshots:
            if snapshot.state == COMPLETE:
                count += 1
        return count

    def get_last_snapshot(self):
        for snapshot in reversed(self.snapshots):
            if snapshot.state in [WARNING, COMPLETE]:
                return snapshot

    def create_snapshot(self):
        logger.debug('Creating snapshot. %r' % {
            'volume_id': self.id,
        })

        if self.snapshot_pending():
            raise SnapshotAlreadyRunning('Snapshot failed, ' + \
                'snapshot already running. %r' % {
                    'volume_id': self.id,
                })

        logger.debug('Starting snapshot task. %r' % {
            'volume_id': self.id,
        })

        task = CreateSnapshot(volume=self)
        task.start()

        return task

    def remove_snapshot(self, snapshot, keep_log=False, block=False):
        task = RemoveSnapshot(volume=self, snapshot=snapshot)
        task.start(keep_log)

        if block:
            task.join()

        return task

    def snapshot_pending(self):
        tasks = Task.get_pending_tasks(self, CREATE_SNAPSHOT)
        if tasks:
            return True
        return False

    def get_space_used(self):
        return 1 - self.get_space_free()

    def get_tasks(self):
        return Task.get_tasks(self)

    def restore_object(self, objects, destination_path):
        logger.debug('Starting restore object task. %r' % {
            'volume_id': self.id,
        })

        task = RestoreObject(volume=self)
        task.start(objects, destination_path)

        return task

    def load(self):
        try:
            Config.load(self)
        except IOError:
            # Config doesnt exists defaults will be used
            pass
        self.origin = Origin(self)

    def load_snapshots(self):
        logger.debug('Loading snapshots. %r' % {
            'volume_id': self.id,
        })

        snapshot_names = []
        self.snapshots = []

        for name in self.list_path(SNAPSHOT_DIR, files=False):
            if not name.replace('.temp', '').replace(
                    '.failed', '').isdigit() or len(name) < 6:
                continue
            snapshot_names.append(name)

        for name in sorted(snapshot_names):
            self.snapshots.append(self.SnapshotClass(self, name))

    def _move_volume(self):
        logger.debug('Starting move volume task. %r' % {
            'volume_id': self.id,
        })

        task = MoveVolume(volume=self)
        task.start()

        return task

    def commit(self):
        Config.commit(self)
        Event(type=VOLUMES_UPDATED)

        if self.orig_path != self.path:
            self._move_volume()

    def _get_log_dir(self):
        return './'

    def _get_auto_excludes(self):
        pass

    def _move_available(self, source_path, destination_path):
        return True

    def _copy_available(self, source_path, destination_path):
        return True

    def get_space_free(self):
        return 1

    def list_path(self, path, files=True, dirs=True):
        return []

@@ -2342,32 +2342,42 @@
 pshot.state in %5B
+REMOVING, 
 WARNING, COMPLET
@@ -4589,73 +4589,12 @@
 name
-.replace('.temp', '').replace(%0A                    '.failed', '')
+%5B:8%5D
 .isd

Add removing state snapshots to default snapshots list