#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2009-2012 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# This utility script is designed to query the mongodb database
# for job history records (Completed or Removed).

# uses pymongo - http://pypi.python.org/pypi/pymongo/
import pymongo
from sys import exit, argv
import time, pwd, os
from optparse import OptionParser
from time import *

# from proc.h
#define JOB_STATUS_MIN      1 /* Smallest valid job status value */
#define IDLE                1
#define RUNNING             2
#define REMOVED             3
#define COMPLETED           4
#define HELD                5
#define TRANSFERRING_OUTPUT 6
#define SUSPENDED           7
#define JOB_STATUS_MAX      7 /* Largest valid job status value */
history_states = {1:'I',2:'R',3:'X',4:'C',5:'H',6:'T',7:'S'}

cluster = None
proc = None
query = {}

def parse_cproc(opts):
    if '.' in opts.cproc:
        return opts.cproc.split('.')
    return (opts.cproc,None)
    
def print_header():
    print "ID".ljust(7),"OWNER".ljust(16),"SUBMITTED".ljust(27),"RUN_TIME".ljust(10),"ST".ljust(3),"COMPLETED".ljust(27),"CMD"
    return True
    
def print_summary(item):
    print str("%s.%s" % (item['ClusterId'],item['ProcId'])).ljust(7), \
                str(item['Owner'].ljust(16)), str(ctime(item['QDate'])).ljust(27), \
                str(strftime('%H:%M:%S', gmtime(item['RemoteWallClockTime']))).ljust(10), str(history_states[item['JobStatus']]).ljust(3), \
                str(ctime(item['CompletionDate'])).ljust(27), str(item['Cmd']), str(item['Args'])
    return True

def print_full_ad(classad):
    for key, value in sorted(classad.items()):
        if str(key) != '_id':
            print key,'=',value
    print
    return True

def build_query(opts):
    if opts.cproc:
        (cluster,proc) = parse_cproc(opts)
        if cluster:
            query['ClusterId'] = int(cluster)
        if proc:
            query['ProcId'] = int(proc)
    if opts.owner:
            query['Owner'] = opts.owner
    if opts.sub:
            query['Submission'] = opts.sub

def print_history(opts):
    build_query(opts)
    opts.long or print_header()
    if opts.forward:
        qdate_order = pymongo.ASCENDING
    else:
        qdate_order = pymongo.DESCENDING
    matches = opts.match or 0 
    try:
        for item in db['history'].find(query).sort('QDate',qdate_order).limit(int(matches)):
            opts.long and print_full_ad(item) or print_summary(item)
    except (KeyError,TypeError,ValueError) as e:
        print "Error in query: ", e
        exit(1)

parser = OptionParser(description='Query Condor ODS for job history')
parser.add_option('-s','--server', action="store", dest='server',
                    default='localhost',
                    help='mongodb database server location: e.g., somehost, localhost:2012')
parser.add_option('-f','--forward', action="store_true", default=False, help='list jobs oldest-to-newest')
parser.add_option('-m','--match', action="store", dest='match', help='limit the number of jobs displayed by <int>')
parser.add_option('-l','--long', action="store_true", default=False, help='verbose output (entire classads)')
parser.add_option('-c','--cproc', action="store", dest='cproc', help='get information about specific cluster[.proc], e.g., 5 or 4.2')
parser.add_option('-o','--owner', action="store", dest='owner', help='information about jobs owned by <owner>')
parser.add_option('-S','--sub', action="store", dest='sub', help='information about jobs grouped by <submission>')

(options, args) =  parser.parse_args()

try:
    connection = pymongo.Connection(options.server)
    db = connection.condor_jobs
except Exception, e:
    print e
    exit(1)

print_history(options)
