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

__all__ = ('TasksCtl',)

from ulib.base.uio import _u, _s
from ulib.base.args import get_args
from factories import get_store
from tasksrc import TasksrcFile

class TasksCtl:
    _tsrc = None
    _stores = None
    _auto_update = True

    def __init__(self, tsrc=None, ctl=None):
        if ctl is None:
            if not isinstance(tsrc, TasksrcFile):
                tsrc = TasksrcFile(tsrc)
            self._tsrc = tsrc
        else:
            self._tsrc = ctl._tsrc
            self._stores = ctl._stores
            self._auto_update = ctl._auto_update

    OPTIONS = 'c:S:s:'
    LONG_OPTIONS = ['config=', 'tasksdir=', 'projdirs=', 'stores=',
                    'tasksfile=', 'purgedfile=',
                    'no-auto-update']

    def get_args(self, args, options=None, longoptions=None):
        return get_args(args, (options or '') + self.OPTIONS,
                        list(longoptions or []) + self.LONG_OPTIONS)

    def is_option(self, option, value):
        if option in ('-c', '--config'):
            self._tsrc = TasksrcFile(value)
            self._stores = None
        elif option in ('--tasksdir',):
            self._tsrc.set_tasksdir(value)
            self._stores = None
        elif option in ('--projdirs',):
            self._tsrc.set_projdirs(value)
        elif option in ('-S', '--stores'):
            self._tsrc.set_stores(value)
            self._stores = None
        elif option in ('-s', '--tasksfile'):
            self._tsrc.set_tasksfile(value)
            self._stores = None
        elif option in ('--purgedfile',):
            self._tsrc.set_purgedfile(value)
        elif option in ('--no-auto-update',):
            self._auto_update = False
        else:
            return False
        return True

    def get_stores(self):
        if self._stores is None:
            self._stores = get_store(self._tsrc.get_tasksfiles())
            if self._auto_update: self._stores.save()
        return self._stores

    def get_wstore(self):
        return self.get_stores().get_wstore()

    def __append(self, list, value):
        if list is None: list = []
        list.append(value)
        return list
    def __setitem(self, dict, name, value):
        if dict is None: dict = {}
        dict[name] = value
        return dict

    def get_filters(self, args, store=None):
        if store is None: store = self.get_stores()
        ids = None
        props = None
        projects = None
        contexts = None
        text = None
        filtered = False
        for arg in args:
            tid, sid = store._parse_id(arg, True)
            name, value = store._parse_prop(arg)
            project = store._parse_project(arg)
            context = store._parse_context(arg)
            if tid is not None: ids = self.__append(ids, (tid, sid))
            elif name is not None: props = self.__setitem(props, name, value)
            elif project is not None: projects = self.__append(projects, project)
            elif context is not None: contexts = self.__append(contexts, context)
            else: text = self.__append(text, arg)
            filtered = True
        if text is not None:
            text = u" ".join(text)
        return ids, text, props, projects, contexts, filtered

    def get_filtered(self, args, required=True, store=None):
        if store is None: store = self.get_stores()
        ids, text, props, projects, contexts, filtered = self.get_filters(map(_u, args), store=store)
        if required and not filtered:
            raise ValueError("A filter is required for this operation")
        tasks = store.find_tasks(ids, text, props, projects, contexts)
        return tasks
