#!/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 os
import sys
import time
import getopt
import threading
import traceback

from ducc_util import DuccUtil
from ducc_base  import DuccProperties
from local_hooks import verify_slave_node
from local_hooks import verify_master_node
from ducc        import Ducc
from ducc_util import ThreadPool

class StartDucc(DuccUtil):

    def start_broker(self):
        
        broker_host = self.ducc_properties.get('ducc.broker.hostname')
        print 'Starting broker on', broker_host
        lines = self.ssh(broker_host, True, "'", self.DUCC_HOME + '/admin/ducc.py', '-c', 'broker', "'")
        while 1:
            line = lines.readline().strip()
            if ( not line ):
                break
            #print '[] ' + line
            if ( line.startswith('PID') ):
                toks = line.split(' ')    # get the PID
                print "Broker on", broker_host, 'PID', toks[1]
                self.pids.put('broker@' + broker_host, toks[1])
                lines.close()
                break

        for i in range(0, 9):
            if ( self.is_amq_active() ):
                return
            print 'Waiting for broker .....', str(i)
            time.sleep(1)

    def start_component(self, args):

        ducc, component, or_parms, single_user = args
        msgs = []

        node = self.ducc_properties.get('ducc.head')
        com = component
        if ( com.find('@') >= 0 ):            
            com, node = com.split('@')

        if ( ((com == 'ws') or (com == 'viz')) and ( node == 'local' ) and ( self.webserver_node != 'localhost' )):
            if ( self.webserver_node != None ):
                node = self.webserver_node
                component = com + '@' + node

        if ((com in self.default_components) or ( com == 'agent')) :
            msgs.append((node, 'Starting', com))
        else:
            msgs.append(('Unrecognized component', component))
            return msgs


        if ( or_parms == None ):
            or_parms = '--or_parms='
        else:
            or_parms = '--or_parms=' + or_parms

        if ( node == 'local' ):
            node = self.localhost

        if ( single_user ):
            lines = self.ssh(node, True, "'", self.DUCC_HOME + '/admin/ducc.py', '-c', com, '-s', '-b', or_parms, '-d', str(time.time()), '--nodup', "'")
        else:
            lines = self.ssh(node, True, "'", self.DUCC_HOME + '/admin/ducc.py', '-c', com, '-b', or_parms, '-d', str(time.time()), '--nodup', "'")

        # we'll capture anything that the python shell spews because it may be useful, and then drop the
        # pipe when we see a PID message
        while 1:
            line = lines.readline().strip()
            if ( not line ):
                break
            #msgs.append(('[]', line))
            if ( line.startswith('PID') ):
                toks = line.split(' ')    # get the PID
                msgs.append(('     PID', toks[1]))
                self.pids.put(com + '@' + node, toks[1])
                lines.close()
                break
            if ( line.startswith('WARN') ):
                msgs.append(('    ', line))
            
        if ( com in self.default_components ):           # tracks where the management processes are
            self.pidlock.acquire()
            self.pids.put(com, com + '@' + node)
            self.pidlock.release()

        return msgs

    def start_one_agent(self, args):

        host, single_user = args
        msgs = []
        spacer = '   '
        msgs.append((host, ""))
        if (single_user):
            lines = self.ssh(host, True, "'", self.DUCC_HOME + '/admin/ducc.py', '-c' 'agent', '-s', '-b', '-d', str(time.time()), '--nodup', "'")
        else:
            lines = self.ssh(host, True, "'", self.DUCC_HOME + '/admin/ducc.py', '-c' 'agent', '-b', '-d', str(time.time()), '--nodup', "'")

        while 1:
            line = lines.readline().strip()
            #msgs.append(('[l]', line))
            if ( line.startswith('PID') ):
                toks = line.split(' ')
                pid = toks[1]
                self.pidlock.acquire()
                self.pids.put('agent@' + host, pid)
                self.pidlock.release()

                lines.close()
                msgs.append((spacer, 'DUCC Agent started PID', pid))
                break

            if ( not line ):
                break
            toks = line.split()

            if ( not self.ssh_ok(host, line ) ):
                break;
            
            if ( toks[0] == 'NOTOK' ):
                msgs.append((spacer, 'NOTOK Not started:', ' '.join(toks[1:])))
            else:
                msgs.append((spacer, line))

        return msgs
      
    def verify_required_directories(self):        
        for dir in ('history', 'state', 'logs'):
            d = self.DUCC_HOME + '/' + dir
            if ( not os.path.exists(d) ):
                print "Initializing", d
                os.mkdir(d)

    def usage(self, *msg):
        if ( msg[0] != None ):
            print ' '.join(msg)

        print "Usage:"
        print "   start_ducc [options]"
        print "        If no options are given, all DUCC processes are started, using the default"
        print "        nodelist, DUCC_HOME/resources/ducc.nodes. "
        print ""
        print "Options:"
        print "   -n --nodelist nodefile"
        print "        Start agents on the nodes in the nodefile.  Multiple nodefiles may be specified:"
        print ""
        print "        start_ducc -n foo.nodes -n bar.nodes -n baz.nodes"
        print ""
        print "   -s --singleuser"
        print "        Start ducc in 'single user mode'.  This bypasses some checking required for multi-user"
        print "        mode and not required for single-user mode."
        print ""
        print "   -c, --component component"
        print "        Start a specific DUCC component, optionally on a specific node.  If the component name"
        print "        is qualified with a nodename, the component is started on that node.  To qualify a"
        print "        component name with a destination node, use the notation component@nodename."
        print "        Multiple components may be specified:"
        print ""
        print "        start_ducc -c sm -c pm -c rm@node1 -c or@node2 -c agent@remote1 -c agent@remote2"
        print ""
        print "        Components include:"
        print "          rm - resource manager"
        print "          or - orchestrator"
        print "          pm - process manager"
        print "          sm - services manager"
        print "          ws - web server"
        print "          viz - visualization server"
        print "          agent - node agent"        
        print ""
        print "    --nothreading"
        print "        Disable multithreaded operation if it would otherwise be used"
        print ""
        print "Examples:"
        print "   Start all DUCC processes, using custom nodelists:"
        print "       start_ducc -n foo.nodes -n bar.nodes"
        print ""
        print "   Start just agents on a specific set of nodes:"
        print "       start_ducc -n foo.nodes -n bar.nodes"
        print ""
        print "   Start the webserver on node 'bingle':"
        print "       start_ducc -c ws@bingle" 
        sys.exit(1)

    def invalid(self, *msg):
        if ( msg[0] != None ):
            print ' '.join(msg)

        print "For usage run"
        print "    start_ducc -h"
        print 'or'
        print '    start_ducc --help'
        sys.exit(1)
    
    def main(self, argv):

        if ( not self.verify_jvm() ):
            sys.exit(1);

        self.get_duccling_version();

        nodefiles = []
        components = []
        single_user = False
        or_parms = self.ducc_properties.get('ducc.orchestrator.start.type')
        self.pids = DuccProperties()
        self.pids.load_if_exists(self.pid_file)
        
        try:
            opts, args = getopt.getopt(argv, 'c:mn:sh?v', ['component=', 'components=', 'help', 'nodelist=', 'singleuser', 'cold', 'warm', 'hot', 'nothreading'])
        except:
            self.invalid('Invalid arguments', ' '.join(argv))
                       
        for ( o, a ) in opts:
            if o in ( '-c', '--components' ): 
                components.append(a)
            elif o in ( '-n', '--nodelist' ):
                nodefiles.append(a)
            elif o in ( '-s', '--singleuser' ):
                single_user = True
            elif o in ( '--nothreading' ):
                self.disable_threading()
            elif o in ( '--cold', '--warm', '--hot' ):
                or_parms = o[2:]         # (strip the leading --)
            elif ( o == '-v'):
                print self.version()
                sys.exit(0)
            elif o in ( '-h', '--help' ):
               self.usage(None)
            elif ( o == '-?'):
                self.usage(None)
            else:
                self.invalid('bad args: ', ' '.join(argv))

        environ = self.show_ducc_environment()
        for e in environ:
            print e

        # no args, or just -s - make equivalent of -management and -nodefile=DUCC.HOME/resources/ducc.nodes
        if ( (len(components) == 0) and (len(nodefiles) == 0 ) ) :
            nodefiles =  self.default_nodefiles
            components = self.default_components

        self.verify_required_directories()

        if ( not verify_master_node(self.ducc_properties) ):
            print 'FAIL: Cannot run javac to run java verification'
            return

        # make sure all the nodefiles exist and are readable
        ok = True
        nodes = {}
        n_nodes = 0
        for n in nodefiles:
            n_nodes, nodes = self.read_nodefile(n, nodes)

        for ( nf, nl ) in nodes.items():
            if ( nl == None ):
                print "Can't read nodefile", nf
                ok = False

        if ok and (nodefiles == self.default_nodefiles):
            if self.verify_class_configuration(nodefiles[0], False):
                print "OK: Class configuration checked"
            else:
                print "NOTOK: Bad configuration, cannot start."
                ok = False

        if ( not ok ):
            sys.exit(1)
                
        if ( not self.verify_limits() ):
            print "Limits too low to run DUCC"
            sys.exit(1)
        
        # activeMQ needs to be started externally before starting any DUCC processes
        if ( self.automanage and ('broker' in components) ):
            if ( self.is_amq_active() ):
                print 'ActiveMQ broker is already running on host and port:', self.broker_host + ':' + self.broker_port, 'NOT restarting'
            else:
                try:
                    self.start_broker()
                except:
                    print sys.exc_info()[0], "DUCC may not be started correctly."
                    sys.exit(1)

        if ( self.is_amq_active() ):
            print 'ActiveMQ broker is found on configured host and port:', self.broker_host + ':' + self.broker_port
        else:
            print 'ActiveMQ broker cannot be found on', self.broker_host + ':' + self.broker_port, 'check', self.DUCC_HOME+'/activemq/data/activemq.log'
            sys.exit(1)

        ducc = Ducc()

        print "Starting", n_nodes, "agents"        
        self.threadpool = ThreadPool(n_nodes + 5)      # a few more for the head processes
        self.pidlock = threading.Lock()
        for (nodefile, nodelist) in nodes.items():
            print '********** Starting agents from file', nodefile
            try:
                for node in nodelist:
                    self.threadpool.invoke(self.start_one_agent, node, single_user)
            except:
                self.threadpool.quit()
                print sys.exc_info()[0], "DUCC may not be started correctly."
                sys.exit(1)
                    
        if ( len(components) != 0 ):
            print 'Starting', or_parms

            for com in components:
                if ( com == 'broker' ):
                    pass     # already started
                else:
                    try:
                        self.threadpool.invoke(self.start_component, ducc, com, or_parms, single_user)
                        #self.start_component(ducc, com, or_parms, single_user)
                    except:
                        self.threadpool.quit()
                        print sys.exc_info()[0], "DUCC may not be started correctly."
                        sys.exit(1)

        self.threadpool.quit()

        if ( len(self.pids) > 0 ):
            self.pids.write(self.pid_file)
        return

if __name__ == "__main__":
    starter = StartDucc()
    starter.main(sys.argv[1:])
