#! /usr/bin/env python
# -----------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.
# -----------------------------------------------------------------------

import datetime
import getpass
import socket
import sys
import time

from HTMLParser import HTMLParser

from optparse import HelpFormatter
from optparse import OptionGroup
from optparse import OptionParser

default_host = 'localhost'
default_port = '42133'
protocol = 'http://'
servlet = '/ducc-servlet/classic-jobs-data'
options = None

sep = '\n'
found = False

# ----------------------------------------------

# Extend OptionParser class
class ExtendedOptionParser(OptionParser):
    # override epilog formatter so 
    # that newlines are not deleted!
    def format_epilog(self, formatter):
        return self.epilog

# ----------------------------------------------

# parser for the jobs WS page
class DuccHtmlParser(HTMLParser):

    token = 0
    
    id = ''
    date = ''
    duration= ''
    user = ''
    sched_class  =''
    state  = ''
    reason = ''
    services  = ''
    processes = ''
    init_fails = ''
    run_fails = ''
    pgin = ''
    swap = ''
    memory = ''
    total = ''
    done = ''
    error = ''
    dispatch = ''
    retry = ''
    preempt = ''
    description = ''
    
    def handle_starttag(self, tag, attrs):
        if(tag == 'tr' ):
            self.token = 0
        elif(tag == 'td' ):
            self.token = self.token + 1
        elif(tag == 'span' ):
            pass
        elif(tag == 'input' ):
            pass
        elif(tag == 'a' ):
            pass
        elif(tag == 'br' ):
            pass
        elif(tag == 'div' ):
            pass
        elif(tag == 'i' ):
            pass
        else:
            debug("start: "+tag)
                    
    def handle_endtag(self, tag):
        global sep
        global options
        global found
        if(options.id == self.id):
            if(tag == 'tr' ):
                found = True
                text = '' \
                    +'id............ '+self.id \
                    +sep \
                    +'date.......... '+self.date \
                    +sep \
                    +'duration...... '+self.duration \
                    +sep \
                    +'user.......... '+self.user \
                    +sep \
                    +'class......... '+self.sched_class \
                    +sep \
                    +'state......... '+self.state \
                    +sep \
                    +'reason........ '+self.reason \
                    +sep \
                    +'services...... '+self.services \
                    +sep \
                    +'processes..... '+self.processes \
                    +sep \
                    +'init_fails.... '+self.init_fails \
                    +sep \
                    +'run_fails..... '+self.run_fails \
                    +sep \
                    +'pgin.......... '+self.pgin \
                    +sep \
                    +'swap.......... '+self.swap \
                    +sep \
                    +'memory........ '+self.memory \
                    +sep \
                    +'total......... '+self.total \
                    +sep \
                    +'done.......... '+self.done \
                    +sep \
                    +'error......... '+self.error \
                    +sep \
                    +'dispatch...... '+self.dispatch \
                    +sep \
                    +'retry......... '+self.retry \
                    +sep \
                    +'preempt....... '+self.preempt \
                    +sep \
                    +'description... '+self.description \
                    +''
                print text
            elif(tag == 'td' ):
                pass
            elif(tag == 'span' ):
                pass
            elif(tag == 'input' ):
                pass
            elif(tag == 'a' ):
                pass
            elif(tag == 'br' ):
                pass
            elif(tag == 'div' ):
                pass
            elif(tag == 'i' ):
                pass
            else:
                debug("end: "+tag)
    
    def handle_data(self, data):
        global options
        if(self.token == 0):
            pass
        elif(self.token == 1):
            pass
        # Id
        elif(self.token == 2):
            self.id = data
        if(options.id == self.id):
            # Start
            if(self.token == 3):
                self.date = data
            # Duration
            elif(self.token == 4):
                self.duration = self.duration+data
            elif(self.token == 5):
                self.user = data
            elif(self.token == 6):
                self.sched_class = data
            elif(self.token == 7):
                self.state = data
            elif(self.token == 8):
                self.reason = data
            elif(self.token == 9):
                self.services = data
            elif(self.token == 10):
                self.processes = data
            elif(self.token == 11):
                self.init_fails = data    
            elif(self.token == 12):
                self.run_fails = data    
            elif(self.token == 13):
                self.pgin = data    
            elif(self.token == 14):
                self.swap = data      
            elif(self.token == 15):
                self.memory = data    
            elif(self.token == 16):
                self.total = data        
            elif(self.token == 17):
                self.done = data    
            elif(self.token == 18):
                self.error = data     
            elif(self.token == 19):
                self.dispatch = data        
            elif(self.token == 20):
                self.retry = data    
            elif(self.token == 21):
                self.preempt = data    
            elif(self.token == 22):
                self.description = data   
            else:
                debug("token: "+str(self.token)+" "+"data: "+data)
            
# -----------------------------------------------------------------------

# epilog for --help
def get_epilog():
    epilog = ''
    return epilog

# produce a time stamp
def get_timestamp():
    tod = time.time()
    timestamp = datetime.datetime.fromtimestamp(tod).strftime('%Y-%m-%d %H:%M:%S')         
    return timestamp

# to console
def to_stdout(text):
    try:
        print text
    except:
        pass
    try:
        sys.stdout.flush()
    except:
        pass
        
def close():
    try:
        sys.stdout.close()
    except:
        pass

# check for log-style formating of text message
def is_log_format():
    retVal = False
    try:
        if(not options == None):
            if(options.flag_log_format):
                retVal = True
    except Exception:
        pass
    return retVal

# info message to log
def info(text):
    prefix = ''
    if(is_log_format()):
        type = 'I'
        prefix = get_timestamp()+' '+type+' '
    line = prefix+text
    to_stdout(line)

# debug message
def debug(text):
    global options
    if(not options == None):
        if(options.flag_debug):
            prefix = ''
            if(is_log_format()):
                type = 'D'
                prefix = get_timestamp()+' '+type+' '
            line = prefix+text
            to_stdout(line)

# error message
def error(text):
    prefix = ''
    if(is_log_format()):
        type = 'E'
        prefix = get_timestamp()+' '+type+' '
    line = prefix+text
    to_stdout(line)

# exception
def exception(e):
    to_stdout(str(e))

# id is required
def validate_id():
    global options
    if(not options.id):
        error('required "id" not specified')
        exit(1)

# --target host:port of WS for fetching of daemons status
def validate_target():
    global options
    global default_host
    global default_port
    global protocol
    global servlet
    target = options.target
    if(':' not in target):
        target = target+':'+default_port
    if(target.startswith(protocol)):
        target = target.replace(protocol,'',1)
    options.ducc_url_base = protocol+target
    options.ducc_url_servlet = protocol+target+servlet
    debug('target: '+options.ducc_url_base)

# parse command line
def parse_cmdline():
    global options
    parser = ExtendedOptionParser(epilog=get_epilog())
    width = 45
    parser.formatter.help_position = width
    parser.formatter.max_help_position = width
    parser.add_option('--id', action='store', dest='id', default=None,
                               help='[REQUIRED] id of job to query')
    parser.add_option('--debug', action='store', dest='flag_debug', default=False,
                               help='display debugging information')
    parser.add_option('--target', action='store', dest='target', default=default_host+':'+default_port,
                               help='<host>:<port> with default of '+default_host+':'+default_port)

    (options, args) = parser.parse_args()
    
    # -id
    validate_id()
    
    # -target
    validate_target()

# fetch current daemons state
def fetch_state_current():
    global options
    import urllib2
    try:
        opener = urllib2.build_opener()
        response = opener.open(options.ducc_url_servlet)
        options.ducc_raw_data = response.read()
        debug(options.ducc_raw_data)
    except Exception,e:
        error('unable to fetch data from '+options.ducc_url_servlet)
        exception(e)
        exit(1)

# transform raw data               
def transform():
    global options
    global head_daemons
    global found
    try:
        parser = DuccHtmlParser()
        parser.feed(options.ducc_raw_data)
        if(found == False):
            print options.id+' '+'not found'
    except Exception,e:
        error('unable to transform data from '+options.ducc_url_servlet)
        exception(e)
        exit(1)

def main(argv):
    global default_host
    try:
        from ducc_base import DuccBase
        base = DuccBase()
        default_host = base.ducc_properties.get('ducc.head')
        parse_cmdline()
        fetch_state_current()
        transform()
        
    except Exception,e:
        error('exception in main')
        exception(e)
             
if __name__ == '__main__':
    main(sys.argv[1:])
