# @GPL_HEADER_START
# Use of the RAVE and related source code is subject to the terms
# of the following licenses:
# 
# GNU Public License (GPL) Rights pursuant to Version 2, June 1991
# Government Purpose License Rights (GPLR) pursuant to DFARS 252.225-7013
# 
# NO WARRANTY
# 
# ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER
# PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY
# PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN
# "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
# KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT
# LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE,
# MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE
# OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT,
# SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY
# TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF
# WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES.
# LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF
# CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON
# CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE
# DELIVERABLES UNDER THIS LICENSE.
# 
# Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie
# Mellon University, its trustees, officers, employees, and agents from
# all claims or demands made against them (and any related losses,
# expenses, or attorney's fees) arising out of, or relating to Licensee's
# and/or its sub licensees' negligent use or willful misuse of or
# negligent conduct or willful misconduct regarding the Software,
# facilities, or other rights or assistance granted by Carnegie Mellon
# University under this License, including, but not limited to, any
# claims of product liability, personal injury, death, damage to
# property, or violation of any laws or regulations.
# 
# Carnegie Mellon University Software Engineering Institute authored
# documents are sponsored by the U.S. Department of Defense under
# Contract F19628-00-C-0003. Carnegie Mellon University retains
# copyrights in all material produced under this contract. The U.S.
# Government retains a non-exclusive, royalty-free license to publish or
# reproduce these documents, or allow others to do so, for U.S.
# Government purposes only pursuant to the copyright license under the
# contract clause at 252.227.7013.
# 
# @GPL_HEADER_END
import sys
import time

from rave.cache.core import Cache, NOW, NEVER
from rave.util.options import OptionList, Option
from rave.plugins.times import parse_any_datetime

opts = [
    ['r' , 'repository', 'path'  , str, "Path to repository"],
    [None, 'print'     , 'string', str, "Print meta-information"],
    # Predicates
    ['t' , 'mime-type' , 'string', str, "MIME type of selected files"],
    ['n' , 'op-name'   , 'string', str, "Name of op used to create entry"],
    ['f' , 'op-file'   , 'string', str, "Filename of op used to create entry"],
    ['v' , 'op-version', 'string', str, "Version of op used to create entry"],
    ['e' , 'expires'   , 'string', str, "Expires at this time"],
    ['b' , 'before'    , 'string', str, "Expires before this time (TODO)"],
    ['a' , 'after'     , 'string', str, "Expires after this time (TODO)"],
]

def datecmp(expires, value):
    # Return:
    # -1 if expires < value,
    #  0 if expires == value,
    #  1 if expires > value
    # value should always be what is passed in from the command-line
    if value == 'NEVER':
        if expires == -1:
            return 0
        return -1
    elif value == 'NOW':
        if expires == 0:
            return 0
        return 1
    else:
        value = parse_any_datetime(value)
        expires = parse_any_datetime(expires)
        if expires < value:
            return -1
        if expires == value:
            return 0
        return 1
    

predicates = {
    'mime-type' : (lambda m,v: m.mime_type == v),
    'op-name'   : (lambda m,v: m.callinfo.op_name == v),
    'op-file'   : (lambda m,v: m.callinfo.op_file == v),
    'op-version': (lambda m,v: m.callinfo.op_version == v),
    'expires'              : (lambda m,v: datecmp(m.expires, v) == 0),
    'expires-before'       : (lambda m,v: datecmp(m.expires, v) <  0),
    'expires-after'        : (lambda m,v: datecmp(m.expires, v) >  0),
    'expires-on-or-before' : (lambda m,v: datecmp(m.expires, v) <= 0),
    'expires-on-or-after'  : (lambda m,v: datecmp(m.expires, v) >= 0),
}

def timefmt(t):
    if t == NOW:
        return "Auto-expire"
    elif t == NEVER:
        return "Never"
    else:
        ftime = time.strftime(
              "%Y-%m-%dT%H:%M:%S", time.localtime(t)) 
        msecs = (t - long(t)) * 1000
        return "%s,%03d" % (ftime, msecs)

def print_meta(meta, value):
    if value == 'info':
        print "%s (%s:%s)" % (meta.callinfo.op_name,
                              meta.callinfo.op_file,
                              meta.callinfo.op_version)
        print "Created: %s; Expires: %s" % (timefmt(meta.created_timestamp),
                                            timefmt(meta.expires))
        print "Arguments:"
        def stringify(x):
            try:
                return str(x)
            except:
                return "(Can't stringify)"
        for k, v in meta.callinfo.args.items():
            print "\t%s: %s" % (stringify(k), stringify(v))
    elif value == 'stub':
        print meta.file_name()[:-5]
    elif value == 'meta':
        print meta.file_name()
    elif value == 'data':
        print meta.data_file()
    elif value == 'both':
        print meta.file_name()
        print meta.data_file()
    else:
        raise RuntimeError("Unrecognized value for print: %s" % value)

def main(args):
    cache = Cache(args.pop('repository'))
    print_style = args.pop('print', 'stub')
    for meta in cache.repository.all_metas():
        satisfied = True
        for k,v in args.items():
            pred = predicates[k]
            if not pred(meta, v):
                satisfied = False
        if satisfied:
            print_meta(meta, print_style)
        

if __name__ == '__main__':
    # Parse arguments
    olist = OptionList.from_options([Option(*x) for x in opts])
    args = olist.parse(sys.argv[1:])
    main(args)
