"""
        search in databases
"""
import re
import time
from datetime import datetime
from datetime import timedelta
from lib.actions import Action
from lib.alpm import AlpmBranch
from lib.displays import DisplayPkg


class ActionSearch(Action):

    @staticmethod
    def usage():
        return """
            search regex --unstable [--desc] [--quiet or -q] [--packager] [--dep] : search in one branch, by default only in pkgname
                --dep [filter]: dependence start by .. , if no "filter" use "regex"
                --packager [filter] : search regex by packager , if no "filter" use "regex"
                --quiet : no show description
                --desc : search in description and package name
                --field field_name : search 'regex' in one field (name, url, buildate,...)
                --format '%n %v %e %d %G %b %p %r %u %P %D' (as expac)
            """

    def test(self):
        super().test()
        if not self.params.branch:
            self.params.branch = 'unstable'
        return True

    def run(self, to_find: str = ''):
        """ command : seach packages by name or description """
        super().run()
        self.msg(f"Branch: {AlpmBranch.color(self.params.branch)}{self.params.branch}{AlpmBranch.color('none')}")
        in_desc = self.params.option('desc')
        by_dep = self.params.option('dep')
        by_date = self.params.option('date')
        by_packager = self.params.option('packager')
        format_model = self.params.option('format')
        by_field = self.params.option('field')
        quiet = self.params.option('quiet', 'q')
        if not to_find:
            try:
                to_find = self.params.values.pop(0)
            except IndexError:
                to_find = ''
        if by_dep:
            if isinstance(by_dep, bool):
                by_dep = to_find
                to_find = ''
            in_desc = True
        if by_packager:
            if isinstance(by_packager, bool):
                by_packager = re.compile(f"<.*{to_find}")
                to_find = ''
            else:
                by_packager = re.compile(f"<.*{by_packager}")
            in_desc = True
        if by_date:
            to_date_reverse = False
            if to_find.endswith('-'):
                to_find = to_find[:-1]
            if to_find.endswith('+'):
                to_find = to_find[:-1]
                to_date_reverse = True
            if to_find.startswith('-'):
                to_date_reverse = True
                by_date = time.mktime((datetime.today() + timedelta(days=int(to_find))).timetuple())
            else:
                by_date = time.mktime(datetime.strptime(to_find, '%Y-%m-%d').timetuple())
            in_desc = True
            to_find = ''

        branch = AlpmBranch(self.params.branch)
        if not format_model:
            if quiet:
                format_model = "{$d%n$n %v:72} (%r)"
            else:
                format_model = "{$d%n$n %v:72} (%r)\n\t$i%d$n"
        display = DisplayPkg(format_model, self.params.branch)
        found = False
        if in_desc:
            for pkg in branch.pkg_search(to_find):
                if by_dep and not [x for x in pkg.depends if x.startswith(by_dep)]:
                    continue
                if by_packager and not by_packager.search(pkg.packager):
                    continue
                if by_date:
                    if to_date_reverse:
                        if by_date > pkg.builddate:
                            continue
                    else:
                        if by_date < pkg.builddate:
                            continue
                found = True
                print(display.string(pkg))
                if by_date:
                    print(f"\t{branch.color('i')}{time.strftime('%a %d %b %Y', time.localtime(pkg.builddate))}{branch.color('none')}")
        else:
            if isinstance(by_field, bool):
                by_field = 'name'
            for pkg in branch.pkg_search_by_field(to_find, by_field):
                found = True
                print(display.string(pkg))
        if not found:
            raise UserWarning(f"Nothing found ! {to_find}")
