#!/usr/bin/python3
"""Tag query.

The idea is something like `tq mpv chill -lyrics`, looking in
`chill.playlist` and `lyrics.playlist` to see if `foo.mp3` is in one
but not the other, passing it to `mpv` if so.

This approach to storing tag data is of limited efficiency; on my
laptop it reads about 500 000 items per second from a single tag file,
or about 20 megabytes per second, whichever is slower, and only up to
about 9000 different tags per second.  This may, however, be adequate
performance for many purposes.  For example, with a 16-millisecond
deadline, you can evaluate up to 8000 tag-item pairs totaling up to
320 kilobytes from up to 144 different tags.  In practice, this
probably means that you can have up to a few tens of thousands of
distinct items tagged before the system starts to get slow.

"""
import os
import sys
import subprocess


def tagquery(terms):
    for i, term in enumerate(terms):
        if not term.startswith('-'):
            cur = read(term)
            terms = terms[:i] + terms[i+1:]
            break
    else:         # All negative query; assume universe is `.`
        cur = set(os.listdir('.'))

    for term in terms:
        cur = cur - read(term[1:]) if term.startswith('-') else cur & read(term)

    return cur


def read(tag):
    if not tag.endswith('.playlist'):
        tag = '{}.playlist'.format(tag)

    with open(tag) as f:
        return set(line[:-1] if line.endswith('\n') else line
                   for line in f)


# Notes on improving UI for tagging:

# I figured you could run lsof to find out what the currently playing
# song or whatever was, and have a `tag` program to add whatever.mp4 to
# foo.playlist and bar.playlist.

# lsof output looks like this, which is probably adequate to guess:

#     mpv     9366 user    8r      REG              252,1 69018724 1576876 /home/user/Downloads/music/Blue Man Group - NPR Music Tiny Desk Concert-qTJfITfbYNA.mp4
#     mpv     9366 user    9r     FIFO               0,10      0t0  110933 pipe
#     mpv     9366 user   10w     FIFO               0,10      0t0  110933 pipe
#     mpv     9366 user   11u     unix 0x0000000000000000      0t0  110934 type=STREAM
#     mpv     9366 user   12u      CHR              226,0      0t0     353 /dev/dri/card0
#     mpv     9366 user   13r     FIFO               0,10      0t0  110944 pipe


if __name__ == '__main__':
    subprocess.run([sys.argv[1]] + list(tagquery(sys.argv[2:])))
