#! /usr/local/bin/python
# Add/remove/update/dump directors
from __future__ import print_function

import sys, os
import optparse
from bacula_tools import *

# {{{ reload_director(): use bconsole to reload the config

def reload_director(d):
    handle = BDirector(d)
    handle.auth()
    handle.send('reload')
    handle.recv_all()
    handle.send('status dir days=')
    handle.recv_all()

# }}}
# {{{ reload_storage(): Restart bacula-sd with appropriate precautions.  Relies on at

def reload_storage():
    atjob = "/tmp/restart_storage.sh"
    cf = ConfigFile(atjob)
    resubmit = cf.close('''
exec > %(atjob)s.log 2>&1
set -x
status=`echo status dir days=0 | bconsole | grep -i "No Jobs running"`
if [ -z "$status" ]
then
  at -f %(atjob)s now + 1 hour
  exit
fi
service bacula-sd restart
/bin/rm %(atjob)s
''' % locals())
    if resubmit: os.system("at -f %(atjob)s now + 1 minute" % locals())
    return

# }}}

# {{{ Parser configuration and sanity checking.  Also, "bacula" is instantiated in here

parser = optparse.OptionParser(description='Print Bacula configuration.', usage='usage: %prog --(director|fd|sd) hostname ')
parser.add_option('--bconsole', action='store_true',
                   default=False, help='Produce a configuration for using bconsole')
parser.add_option('--director', action='store_true',
                   default=False, help='Produce a configuration for the given director')
parser.add_option('--fd', action='store_true',
                   default=False, help='Produce a configuration for the given file daemon')
parser.add_option('--sd', action='store_true',
                   default=False, help='Produce a configuration for the given storage daemon')

keylist = [DIRECTOR, FD, SD, BCONSOLE]
(args, given_arg) = parser.parse_args()
foo = [x for x in keylist if getattr(args, x)]

if len(foo) != 1:
    print('You must use one, and only one, option\n')
    parser.print_help()
    exit()

if (not given_arg) or not len(given_arg) == 1:
    print('You must supply the name of the configuration host\n')
    parser.print_help()
    exit()

bacula = Bacula_Factory()        # Instantiate our DB connection thingy
# }}}

hostname = given_arg[0].strip()

if args.director:
    # {{{ Director configuration stanzas

    # First, the basics
    cf = ConfigFile(BACULA_DIR_CONF)
    d = Director().search(hostname)
    cf.write(d, '\n')
    c = Catalog({DIRECTOR_ID: d[ID]}).search()
    cf.write(c, '\n')
    for id in d.bc.do_sql('SELECT messages_id FROM messages_link where ref_id = %s and link_type = %s', (d[ID], d.IDTAG)): cf.write( Messages().search(id), '\n')
    # Now, for a little more interesting stuff (and we're cheating hard)
    for id in d.bc.do_sql('SELECT id FROM filesets ORDER BY name'): cf.write( Fileset().search(id), '\n')
    for id in d.bc.do_sql('SELECT id FROM schedules ORDER BY name'): cf.write( Schedule().search(id), '\n')
    # clients
    for id in d.bc.do_sql('SELECT id FROM clients ORDER BY name'): cf.write( Client(director_id = d[ID]).search(id), '\n')
    # jobs
    for id in d.bc.do_sql('SELECT id FROM jobs WHERE jobdef=1 ORDER BY name'): cf.write( JobDef().search(id), '\n')
    for id in d.bc.do_sql('SELECT id FROM jobs WHERE NOT jobdef=1 ORDER BY name'): cf.write( Job().search(id), '\n')
    # storage
    for id in d.bc.do_sql('SELECT id FROM storage ORDER BY name'): cf.write( Storage(director_id = d[ID]).search(id), '\n')
    # Pools
    for id in d.bc.do_sql('SELECT id FROM pools ORDER BY name'): cf.write( Pool().search(id), '\n')
    if cf.close(): reload_director(d)

    # }}}
    

if args.fd:
    # {{{ File Daemon configuration stanzas

    cf = ConfigFile(BACULA_FD_CONF)
    cl = Client().search(hostname)
    cf.write(cl.fd(), '\n')

    for id in cl.bc.do_sql('SELECT director_id FROM client_pwords where client_id = %s ORDER BY director_id', cl[ID]):
        cf.write( Director(client_id = cl[ID]).search(id).fd(), '\n')
    
    for id in cl.bc.do_sql('SELECT messages_id FROM messages_link WHERE ref_id = %s AND link_type = %s', (cl[ID], cl.IDTAG)): cf.write( Messages().search(id), '\n')
    if cf.close(): pass

    # }}}

if args.sd:
    cf = ConfigFile(BACULA_SD_CONF)
    sd = Storage().search(hostname)
    cf.write(sd.sd(), '\n')

    for id in sd.bc.do_sql('SELECT director_id FROM storage_pwords where storage_id = %s ORDER BY director_id', sd[ID]):
        cf.write( Director(storage_id = sd[ID]).search(id).sd(), '\n')
    
    for id in sd.bc.do_sql('SELECT device_id FROM device_link WHERE storage_id = %s', sd[ID]):
        cf.write( Device().search(id), '\n')
        
    for id in sd.bc.do_sql('SELECT messages_id FROM messages_link WHERE ref_id = %s AND link_type = %s', (sd[ID], sd.IDTAG)):
        cf.write( Messages().search(id), '\n')
    if cf.close(): pass
