# -*- coding: utf-8 -*-

import functools

from .. import exceptions
from ..utils import uniq


def mutating_storage_method(f):
    @functools.wraps(f)
    def inner(self, *args, **kwargs):
        if self.read_only:
            raise exceptions.ReadOnlyError('This storage is read-only.')
        return f(self, *args, **kwargs)
    return inner


class StorageMeta(type):
    def __init__(cls, name, bases, d):
        for method in ('update', 'upload', 'delete'):
            setattr(cls, method, mutating_storage_method(getattr(cls, method)))
        return super(StorageMeta, cls).__init__(name, bases, d)


class Storage(metaclass=StorageMeta):

    '''Superclass of all storages, interface that all storages have to
    implement.

    Terminology:
      - ITEM: Instance of the Item class, represents a calendar event, task or
          contact.
      - HREF: String; Per-storage identifier of item, might be UID. The reason
          items aren't just referenced by their UID is because the CalDAV and
          CardDAV specifications make this unperformant to implement.
      - ETAG: String; Checksum of item, or something similar that changes when
          the item does.