# ----------------------------------------------------------------------
#    Copyright (c) 2009 CSC Ltd. (http://www.csc.fi)
#    (All rights reversed)
#    Based on "getPoolInfos.py"  from DCACHE.ORG (R)
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of version 2 of the GNU General Public
#    License published by the Free Software Foundation.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, contact Novell, Inc.
# ----------------------------------------------------------------------
#
from org.pcells.services.connection import *
from dmg.protocols.ssh import *
from dmg.cells.nucleus import NoRouteToCellException
from java.lang import System
from java.io import File
from java.io import FileNotFoundException
import sys,time,types,string,re


connectionStartID=1
MoverQueueRegEx=re.compile("Mover Queue \((\S+)\) (.*)")
MoverLSRegEx=re.compile("(\d+) (\S+) (\S+) \{(\S+)\} (\S+) h=\{(\S+)\} bytes=(\d+) time/sec=(\d+) LM=(\d+)")
DEBUG=False

class ourDomainEventListener( DomainEventListener) :

   def __init__(self,MyPools) :
       self.Pools=MyPools
       return

   def connectionOpened( self , connection ) :
       # send first command here
       connection.sendObject( "PoolManager" , "psu ls pool" , MyMessageListener , connectionStartID ) ;
       
   def connectionClosed( self , connection ) :
          print "Connection closed"

   def connectionOutOfBand( self , connection , subject ) :
          print "Connection out of band"

class ourDomainConnectionListener( DomainConnectionListener ) :

   #
   # this class only has one object in the application which
   # is used whenever data arrives from the channel.
   #

    def __init__( self, MyPools ) :
        self.Pools=MyPools
        self.currentID=connectionStartID
        self.currentMoverID=0
        self.currentPoolID=0
        return

    def getMovers(self,obj) :
        self.Pools.MoverInfo.append({})
        for line in obj.split("\n") :
            if not "Mover Queue (" in line : continue
            matchObj=MoverQueueRegEx.match(line)
            if matchObj :
                queue,conns=matchObj.groups()
            else :
                queue,conns=("N/A","N/A")
            self.Pools.MoverInfo[self.currentPoolID][queue]=conns
        self.currentPoolID +=1
        if self.currentPoolID < len(self.Pools.PoolList) :
            self.currentID += 1
            connection.sendObject(self.Pools.PoolList[self.currentPoolID], "info",MyMessageListener, self.currentID )
        return

    def getDetailedMoverInfo(self,obj)  :
        self.Pools.MoverDetail.append([])
        for line in obj.split("\n") :
            line=line.strip()
            if len(line) == 0 : continue
            tmpDict={}
            matchObj=MoverLSRegEx.match(line)
            if DEBUG :
               print line,matchObj
            if matchObj :
               f1,State,Type,Cell,pnfsID,javastuff,bytes,speed,LM =matchObj.groups()
            else :
               f1,State,Type,Cell,pnfsID,javastuff,bytes,speed,LM = ("N/A","N/A","N/A","N/A","N/A","N/A","N/A","N/A","N/A") 
            tmpDict["State"]=State
            tmpDict["Type"]=Type
            tmpDict["Cell"]=Cell
            tmpDict["pnfsID"]=pnfsID
            tmpDict["Bytes"]=bytes
            tmpDict["Speed"]=speed
            self.Pools.MoverDetail[-1:][0].append(tmpDict)
            self.Pools.TotalMovers += 1
        self.currentPoolID +=1
        if self.currentPoolID < len(self.Pools.PoolList) :
            self.currentID += 1
            connection.sendObject(self.Pools.PoolList[self.currentPoolID], "mover ls",MyMessageListener, self.currentID )
        return

    def domainAnswerArrived( self , obj , id ) :
       if DEBUG :
           print "id=%d,border1=%d" % (id,connectionStartID + len(self.Pools.PoolList))
           print "currentPoolID =%d" % self.currentPoolID
       if id == connectionStartID :
          for p in obj.split("\n") :
	      p=p.strip()
              if len(p) == 0 :continue
              self.Pools.PoolList.append(p)
          if len(self.Pools.PoolList) > 0 : 
              self.currentID += 1
              connection.sendObject(self.Pools.PoolList[self.currentPoolID], "info",MyMessageListener, self.currentID )
       elif id == connectionStartID +1 :
           self.getMovers(obj)
       elif id > connectionStartID +1 and id < connectionStartID + len(self.Pools.PoolList)  :
           self.getMovers(obj)
       elif id == connectionStartID + len(self.Pools.PoolList) :
           self.getMovers(obj)
           self.currentID += 1
           self.currentPoolID=0
           connection.sendObject(self.Pools.PoolList[self.currentPoolID], "mover ls",MyMessageListener, self.currentID )
       elif id > connectionStartID + len(self.Pools.PoolList) and id <  connectionStartID + 2 * len(self.Pools.PoolList) :
           self.getDetailedMoverInfo(obj)
       else :
           self.getDetailedMoverInfo(obj)
           self.Pools.html_dump()
           System.exit(0)
        
    

class Pools :

    def __init__(self) :
        self.PoolList=[]
        self.MoverInfo=[]
        self.MoverDetail=[]
        self.TotalMovers=0
        return

    def dump(self) :
        self.PoolList.sort() 
        print "PoolList : %s" % string.join(self.PoolList,",")
        print "Info :"
        for i in range(len(self.PoolList)) :
            print "Mover queues Pool %s :" %  self.PoolList[i]
            for q in self.MoverInfo[i] :
                print "* %s : %s " % (q,self.MoverInfo[i][q])
        for i in range(len(self.PoolList)) :
            print "Detailed Mover info Pool %s :" %  self.PoolList[i]
            for j in range(len(self.MoverDetail[i])) :
                for q in self.MoverDetail[i][j] :
                    print "%s : %s " % (q,self.MoverDetail[i][j][q])
                print "-------------"
        return

    def html_dump(self) :
        print """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
<title>HIP/CSC Storage Element</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Refresh" content="60">
<link rel="stylesheet" type="text/css" href="/duchess.css">
<!-- sorttable from http://www.kryogenix.org/code/browser/sorttable/ -->
<script src="/sorttable.js"></script>
</head>
<body>
"""
        print "<h1>All Active Connections</h1>" 
        print "Updated at: %s<br/>" % time.asctime(time.localtime())
        print "Total number of movers : %s<br/>" %  self.TotalMovers
        print "<i>For sorting by column click on the table headers</i><br/>"
        print '<table border="1" class="sortable">'
        print "<thead><tr>"
        print "<th>Pool</th>"
        print "<th>Cell</th>"
        print "<th>Type</th>"
        print "<th>State</th>"
        print "<th>Speed</th>"
        print "<th>pnfsID</th>"
        print "<th>Bytes</th>"
        print "</tr></thead>"
        print "<tbody>"
        for i in range(len(self.PoolList)) :
            for j in range(len(self.MoverDetail[i])) :
                print "<tr>" 
                print "<td> %s</td>" %  self.PoolList[i]
                print "<td>%s</td>" % (self.MoverDetail[i][j]["Cell"])
                print "<td>%s</td>" % (self.MoverDetail[i][j]["Type"])
                print "<td>%s</td>" % (self.MoverDetail[i][j]["State"])
                print "<td>%s</td>" % (self.MoverDetail[i][j]["Speed"])
                print "<td>%s</td>" % (self.MoverDetail[i][j]["pnfsID"])
                print "<td>%s</td>" % (self.MoverDetail[i][j]["Bytes"])
                print "</tr>" 
        print "</tbody>"
        print "</table>"

        print "</body></html>"


#----------------------------------------------------------------------
#
#   Main Routine
#
#----------------------------------------------------------------------
#
if  len(sys.argv) < 5 :
   print "Usage : ... <hostname> <portNumber> <userName> <passwd>"
   System.exit(4)
#
# Define the ListenerObject for all incoming message
#

MyPools=Pools()
MyMessageListener = ourDomainConnectionListener(MyPools)
MyDomainEventListener=ourDomainEventListener(MyPools)
#
#  Define Host and portnumber
#
connection=Ssh1DomainConnection(sys.argv[1],int(sys.argv[2]))
connection.setLoginName(sys.argv[3])
#
# Establish the secret : either password or identity file
#

secret=sys.argv[4]
if secret[0] == "/" :
   connection.setPassword("")
   try :
      connection.setIdentityFile( File(secret) )
   except FileNotFoundException, e :
      print "Authentication Failed ...",e.getMessage()
      System.exit(1)
else :
   connection.setPassword(secret)

connection.addDomainEventListener( MyDomainEventListener )
#
#  and now go
#
try :
   connection.go()
except SshAuthenticationException, e :
   print "Authentication Failed ...",e.getMessage()
   System.exit(1)


