"""
This component will look for files to be removed. There are some assumptions:
    * Only files in $TMPDIR are removed. Please remember that larigira has its
      own specific TMPDIR
    * MPD URIs are parsed, and only file:/// is supported
"""
import os
from os.path import normpath
import logging
import mpd


def old_commonpath(directories):
    if any(p for p in directories if p.startswith("/")) and any(
        p for p in directories if not p.startswith("/")
    ):
        raise ValueError("Can't mix absolute and relative paths")
    norm_paths = [normpath(p) + os.path.sep for p in directories]
    ret = os.path.dirname(os.path.commonprefix(norm_paths))
    if len(ret) > 0 and ret == "/" * len(ret):
        return "/"
    return ret


try:
    from os.path import commonpath
except ImportError:
    commonpath = old_commonpath


class UnusedCleaner:
    def __init__(self, conf):
        self.conf = conf
        self.waiting_removal_files = set()
        self.log = logging.getLogger(self.__class__.__name__)

    def _get_mpd(self):
        mpd_client = mpd.MPDClient(use_unicode=True)
        mpd_client.connect(self.conf["MPD_HOST"], self.conf["MPD_PORT"])
        return mpd_client

    def watch(self, uri):
        """
        adds fpath to the list of "watched" file

        as soon as it leaves the mpc playlist, it is removed
        """
        if not uri.startswith("file:///"):
            return  # not a file URI
        fpath = uri[len("file://") :]
        if (
            "TMPDIR" in self.conf
            and self.conf["TMPDIR"]
            and commonpath([self.conf["TMPDIR"], fpath])
            != normpath(self.conf["TMPDIR"])
        ):
            self.log.info("Not watching file %s: not in TMPDIR", fpath)
            return
        if not os.path.exists(fpath):
            self.log.warning("a path that does not exist is being monitored")
        self.waiting_removal_files.add(fpath)

    def check_playlist(self):
        """check playlist + internal watchlist to see what can be removed"""
        mpdc = self._get_mpd()
        files_in_playlist = {
            song["file"] for song in mpdc.playlistid() if song["file"].startswith("/")
        }
        for fpath in self.waiting_removal_files - files_in_playlist:
            # we can remove it!
            self.log.debug("removing unused: %s", fpath)
            self.waiting_removal_files.remove(fpath)
            if os.path.exists(fpath):
                os.unlink(fpath)
