#!/usr/bin/env python

# Script for restarting archiving device servers
# srubio@cells.es, 2009

import sys,time,os

import PyTango
import PyTangoArchiving as pta
import fandango as fn
from fandango.servers import ServersDict

USAGE = """
    archiving_service [start/stop/status] [all/schemas ...]
    """

#def get_archiving_servers(schema=''):
    #astor = ServersDict()
    #astor.log.setLogLevel(astor.log.Warning)
    
    ##Excluding watchers due to its high CPU usage
    #names = len(sys.argv)>2 and sys.argv[2:] or ['ArchivingManager/*']\
        #+(schema.lower() in ('hdb','') and ['HdbArchiver*/*','HdbExtractor/*'] or [])\
        #+(schema.lower() in ('tdb','') and ['TdbArchiver*/*','TdbExtractor/*'] or [])
    #[astor.load_by_name(name) for name in names]
    #return astor
    
def get_archiving_servers(schemas):
    schemas = fn.toList(schemas)
    astor = fn.Astor()
    for s in schemas:
        devs = []
        api = pta.api(s)
        devs.append(api.get_manager())
        devs.extend(api.get_archivers())
        if hasattr(api,'get_periodic_archivers'):
            devs.extend(api.get_periodic_archivers())
        devs = [(d.dev_name() if hasattr(d,'dev_name') 
                else str(d)) for d in devs]
        astor.load_from_devs_list(devs)
    return astor
    
launch_order = ['archiver','subscriber','es-srv','extractor',
                'manager','cm-srv','watcher']

def main(args):
    if not len(args):
        print(USAGE)
        sys.exit(1)
        
    action,schemas = args[0],args[1:]
    if 'all' in schemas:
        schemas = pta.multi.get_hdbpp_databases()
        print(schemas)
        
    if action == 'status':
        get_archiving_status(schemas)
    elif action == 'start':
        start_archiving(schemas)
    elif action == 'stop':
        stop_archiving(schemas)
    else:
        print(USAGE)

    
    
def get_archiving_status(schemas):
    
    print('Checking the archiving system status ...')
    
    astor = get_archiving_servers(schemas)
    astor.update_states()
    
    running = sorted(['\t'.join((d.name,d.host,str(d.level))) 
                      for d in astor.values() if d.state == PyTango.DevState.ON 
                      and (d.host or d.level)])
    failed = sorted(['\t'.join((d.name,d.host,str(d.level))) 
                     for d in astor.values() if d.state != PyTango.DevState.ON 
                     and (d.host or d.level)])
    disabled = sorted(['\t'.join((d.name,d.host,str(d.level))) 
                       for d in astor.values() if not (d.host or d.level)])
    
    print('\n')
    print("*"*80)
    print('\n')
    
    faulty = []
    goods = []
    dedicated = []
    
    if running:
        for s in running:
            server = s.split()[0]
            if server not in astor: continue
            devs = astor[server].get_device_list()
            for d in devs:
                dp = astor.proxies[d]
                try:
                    dp.ping()
                    if dp.state() == PyTango.DevState.FAULT:
                        faulty.append(d)
                    elif s not in goods:
                        goods.append(s)
                    if dp.get_property(['IsDedicated'])['IsDedicated']:
                        dedicated.append(d)
                    
                except:
                    if d not in faulty:
                        faulty.append(d)
    print '\n'
    if goods:
        print "Servers actually running are:"
        print "-"*40
        print '\n'.join(goods)
        print '\n'
    
    if dedicated:
        print "Devices dedicated are:"
        print "-"*40
        print '\n'.join(dedicated)
        print '\n'
    if faulty:
        print "Devices in FAULT state are:"
        print "-"*40
        print '\n'.join(faulty)
        print '\n'
    if failed:
        print "Servers that are not working:"
        print "-"*40
        print '\n'.join(failed)
        print '\n'
    if disabled:
        print "Servers not registered to any server:"
        print "-"*40
        print '\n'.join(disabled)
        print '\n'

def start_archiving(schemas):
    print('Starting the archiving system ...')
    astor = get_archiving_servers(schemas)
    for name in launch_order:
        ss = [(t.host,t.level,t.name) for t in astor.values()]
        for h,l,n in sorted(ss):
            if name in n.lower():
                print(h,l,n)
                astor.start_servers(n)

    print('Archiving system started')
    
def stop_archiving(schemas):
    print('Stopping the archiving system ...')
    astor = get_archiving_servers(schemas)
    astor.stop_servers()
    #servers = ['dserver/%s'%a for a in astor]
    #for a in sorted(servers):
        #print('killing %s'%a)
        #try: PyTango.DeviceProxy(a).kill()
        #except Exception,e: print('\tfailed: %s'%e)
    print('Archiving system stopped')

if __name__ == '__main__':
    args = sys.argv[1:]
    if len(args)<2:
        print(USAGE)
    else:
        main(args)
    

    
