# -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
import ulib.base.i_need_py23

__all__ = ('SimpleHttpStore',)

from store import AbstractStore, UnsavedModificationError
from multiple import MultipleStore

LASTID = 'lastid'

class SimpleHttpStore(AbstractStore):
    GENERIC_PROPERTIES = AbstractStore.GENERIC_PROPERTIES + [LASTID]

    def __init__(self, url=None):
        AbstractStore.__init__(self)
        self.__reset()
        if url is not None: self.load(url)

    def __reset(self):
        self._tasks = []
        self._lastid = 0
        self._tids = {}

    _tasks, tasks, get_tasks = make_sprop('_tasks', None, setter=False, deleter=False)
    _lastid, lastid, get_lastid, set_lastid, del_lastid = make_suprop('_lastid', 0)

    _tids = None
    def _nextid(self):
        _u = self._uio.u
        nextid = int(self._lastid) + 1
        while self._tids.has_key(_u(nextid)):
            nextid += 1
        self._lastid = nextid
        return nextid

    def _ensure_tid(self, task):
        if task._tid is None: task.tid = self._nextid()

    def _task_attached(self, task, validate=False):
        self._ensure_tid(task)
        if not self._tids.has_key(task._tid):
            self._tids[task._tid] = task
        AbstractStore._task_attached(self, task, validate)

    def remove(self, task):
        if task not in self._tasks: return False
        del self._tids[task._tid]
        self._tasks.remove(task)
        self._modified = True
        return True

    _url = None
    _name = None

    def get_name(self):
        return _u(self._name)
    name = property(get_name)

    RE_SPROPS = re.compile(r'##\s+sprops:')
    def load(self, infdn=None, force=False):
        if self.is_modified() and not force:
            raise UnsavedModificationError

        if infdn is None:
            infdn = self._url
            if infdn is None: raise ValueError("Source url is required")
        else:
            self._url = infdn
            _, self._name = path.split(self._url)
        self.__reset()
        self._valid = False
        lines = Lines()
        # XXX corriger à partir d'ici
        if path.exists(infdn):
            lines.readlines(infdn, open_func=rdopen)
            for line in lines:
                if self.RE_SPROPS.match(line) is not None:
                    self.set_props(**self._line2props(line, False))
                elif not line.strip() or line.startswith(u'#'):
                    # ignorer lignes vides et commençant par "#"
                    pass
                else:
                    task = self._tf.build_task(**self._line2props(line))
                    self.tasks.append(task)
                    self._task_attached(task, True)
        self._modified = False
        self._valid = True

    def __is_sprop(self, line):
        return self.RE_SPROPS.match(line) is not None

    def should_reload(self):
        infdn = self._fdn
        if infdn is None: return False
        if not path.exists(infdn): return False
        lines = Lines()
        lines.readlines(infdn, open_func=rdopen, until=self.__is_sprop)
        props = {}
        for line in lines:
            if self.RE_SPROPS.match(line) is not None:
                props = self._line2props(line, False)
                break
        return self.serial != props.get(SERIAL, None)
