import fnmatch
import logging
import os
import pathlib

from mini_buildd import files, util

LOG = logging.getLogger(__name__)


class Dir:
    def __init__(self, basedir, pooldir="pool", sources_glob="*/*/*"):
        self.path = pathlib.Path(basedir, pooldir)
        self.sources_glob = sources_glob

    BINARY_SUFFIXES = [".deb", ".udeb", ".ddeb"]

    def isearch(self, pattern):
        """Search pattern in all source or binary package names, return matching source package names"""
        for s in self.path.glob(self.sources_glob):
            if fnmatch.fnmatch(s.name, pattern):
                yield s.name, s
            for f in (f for f in s.rglob("*") if f.suffix in self.BINARY_SUFFIXES):
                binary = f.name.partition("_")[0]
                if fnmatch.fnmatch(binary, pattern):
                    yield s.name, f

    def dsc_path(self, source, version, raise_exception=True):
        """Get DSC pool path of an installed source (``<repo>/pool/...``)"""
        dscs = list(self.path.glob(os.path.join("*", "*", source, files.DebianName(source, version).dsc())))

        LOG.debug("Pool %s: Found pool DSCs for '%s-%s': %s", self.path, source, version, dscs)

        if len(dscs) > 1:  # This should not really ever happen. Pool-wise it could however with different components (main, contrib, etc)
            LOG.warning("Found multiple DSCs for '%s-%s' in pool (only the 1st found will be used)", source, version)
            for d in dscs:
                LOG.warning("↳ %s", d)

        if len(dscs) < 1:
            msg = f"Can't find DSC for '{source}-{version}' in pool '{self.path}'"
            if raise_exception:
                raise util.HTTPBadRequest(msg)
            LOG.warning(msg)
            return None

        return str(dscs[0].relative_to(self.path.parent.parent))


if __name__ == "__main__":
    pool = Dir("/var/lib/mini-buildd/repositories/test")
    print(set(pool.isearch("*")))
