#
# Copyright (C) 2017 J.F.Dockes
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Manage the 'untagged' section of the tree.  Our selection is made of
# all tracks without a 'title' field. This is different from what
# Minimserver does (I think that more or less any field present makes
# a track not untagged for minim).
#
# Initialization filters the untagged tracks and creates a vector of
# indexes into the global doc vector.
#
# Object Id prefix: 0$uprcl$untagged
# 
# Obect id inside the section: $u<idx> where <idx> is the document index
#  inside the global document vector.

import os
import shlex
import sys

from upmplgutils import uplog
from uprclutils import rcldoctoentry, rcldirentry

class Untagged(object):
    def __init__(self, docs, httphp, pathprefix):
        self._idprefix = '0$uprcl$untagged'
        self._httphp = httphp
        self._pprefix = pathprefix
        self.recoll2untagged(docs)
        
    # Create the untagged entries static vector by filtering the global
    # doc vector, storing the indexes of all tracks without a title
    # field. We keep a reference to the doc vector.
    def recoll2untagged(self, docs):
        self.rcldocs = docs
        # The -1 entry is because we use index 0 for our root.
        self.utidx = [-1]
    
        for docidx in range(len(docs)):
            doc = docs[docidx]
            if doc.mtype == 'inode/directory':
                continue
            if not doc.title:
                self.utidx.append(docidx)

    # Compute index into our entries vector by 'parsing' the objid.
    def _objidtoidx(self, pid):
        if not pid.startswith(self._idprefix):
            raise Exception("untagged:browse: bad pid %s" % pid)

        if len(self.rcldocs) == 0:
            raise Exception("untagged:browse: no docs")

        idx = pid[len(self._idprefix):]
        if not idx:
            # Browsing the root.
            idx = 0
        else:
            if idx[1] != 'u':
                raise Exception("untagged:browse: called on bad objid %s" % pid)
            idx = int(idx[2:])
    
        if idx >= len(self.utidx):
            raise Exception("untagged:browse: bad pid %s" % pid)

        return idx

    # Return entry to be created in the top-level directory ([untagged]).
    def rootentries(self, pid):
        return [rcldirentry(pid + 'untagged', pid, '[untagged]'),]


    # Browse method
    # objid is like untagged$u<index>
    # flag is meta or children.
    def browse(self, pid, flag):
        idx = self._objidtoidx(pid)

        entries = []
        if idx == 0:
            # Browsing root
            for i in range(len(self.utidx))[1:]:
                doc = self.rcldocs[self.utidx[i]]
                id = self._idprefix + '$u' + str(i)
                e = rcldoctoentry(id, pid, self._httphp, self._pprefix, doc)
                if e:
                    entries.append(e)
        else:
            # Non root: only items in there. flag needs to be 'meta'
            doc = self.rcldocs[thisdocidx]
            id = self._idprefix + '$u' + str(idx)
            e = rcldoctoentry(id, pid, self._httphp, self._pprefix, doc)
            if e:
                entries.append(e)

        return sorted(entries, key=lambda entry: entry['tt'].lower())
