
from DIRAC.WorkloadManagementSystem.Client.SandboxStoreClient import SandboxStoreClient
from WebAppDIRAC.Lib.WebHandler import WebHandler, WErr, WOK, asyncGen
from DIRAC.Core.DISET.RPCClient import RPCClient
from DIRAC import gConfig, S_OK, S_ERROR, gLogger
from DIRAC.Core.Utilities import Time
from WebAppDIRAC.WebApp.handler.Palette import Palette
from DIRAC.RequestManagementSystem.Client.Request       import Request
import json


class JobMonitorHandler( WebHandler ):

  AUTH_PROPS = "authenticated"

  @asyncGen
  def web_getJobData( self ):
    RPC = RPCClient( "WorkloadManagement/JobMonitoring", timeout = 600 )
    req = self._request()

    result =
 yield self.threadTask(
 RPC.getJobPageSummaryWeb, req, self.globalSort , self.pageNumber, self.numberOfJobs )

    if not result["OK"]:
      self.finish( {"success":"false", "result":[], "total":0, "error":result["Message"]} )
      return

    result = result["Value"]

    if not result.has_key( "TotalRecords" ):
      self.finish( {"success":"false", "result":[], "total":-1, "error":"Data structure is corrupted"} )
      return


    if not ( result["TotalRecords"] > 0 ):
      self.finish( {"success":"false", "result":[], "total":0, "error":"There were no data matching your selection"} )
      return


    if not ( result.has_key( "ParameterNames" ) and result.has_key( "Records" ) ):
      self.finish( {"success":"false", "result":[], "total":-1, "error":"Data structure is corrupted"} )
      return

    if not ( len( result["ParameterNames"] ) > 0 ):
      self.finish( {"success":"false", "result":[], "total":-1, "error":"ParameterNames field is missing"} )
      return

    if not ( len( result["Records"] ) > 0 ):
      self.finish( {"success":"false", "result":[], "total":0, "Message":"There are no data to display"} )
      return

    callback = []
    jobs = result["Records"]
    head = result["ParameterNames"]
    headLength = len( head )
    for i in jobs:
      tmp = {}
      for j in range( 0, headLength ):
        tmp[head[j]] = i[j]
      callback.append( tmp )
    total = result["TotalRecords"]
    if result.has_key( "Extras" ):
      st = self.__dict2string( {} )
      extra = result["Extras"]
      timestamp = Time.dateTime().strftime( "%Y-%m-%d %H:%M [UTC]" )
      callback = {"success":"true", "result":callback, "total":total, "extra":extra, "request":st, "date":timestamp }
    else:
      callback = {"success":"true", "result":callback, "total":total, "date":None}
    self.finish( callback )

  def __dict2string( self, req ):
    result = ""
    try:
      for key, value in req.iteritems():
        result = result + str( key ) + ": " + ", ".join( value ) + "; "
    except Exception, x:
      pass
      gLogger.info( "\033[0;31m Exception: \033[0m %s" % x )
    result = result.strip()
    result = result[:-1]
    return result

  @asyncGen
  def web_getSelectionData( self ):
    sData = self.getSessionData()
    
    callback = {}

    user = sData["user"]["username"]
    if user == "Anonymous":
      callback["prod"] = [["Insufficient rights"]]
    else:
      RPC = RPCClient( "WorkloadManagement/JobMonitoring" )
      result = yield self.threadTask( RPC.getProductionIds )
      if result["OK"]:
        prod = []
        prods = result["Value"]
        if len( prods ) > 0:
          prods.sort( reverse = True )
          prod = [ [ i ] for i in prods if i.startswith('00')]
        else:
          prod = [["Nothing to display"]]
      else:
        gLogger.error( "RPC.getProductionIds() return error: %s" % result["Message"] )
        prod = [["Error happened on service side"]]
      callback["prod"] = prod
# ##
    RPC = RPCClient( "WorkloadManagement/JobMonitoring" )
    result = yield self.threadTask( RPC.getSites )
    if result["OK"]:
      tier1 = gConfig.getValue( "/Website/PreferredSites", [] )  # Always return a list
      site = []
      if len( result["Value"] ) > 0:
        s = list( result["Value"] )
        for i in tier1:
          site.append( [str( i )] )
        for i in s:
          if i not in tier1:
            site.append( [str( i )] )
      else:
        site = [["Nothing to display"]]
    else:
      gLogger.error( "RPC.getSites() return error: %s" % result["Message"] )
      site = [["Error happened on service side"]]
    callback["site"] = site
# ##
    result = yield self.threadTask( RPC.getStates )
    if result["OK"]:
      stat = []
      if len( result["Value"] ) > 0:
        for i in result["Value"]:
          stat.append( [str( i )] )
      else:
        stat = [["Nothing to display"]]
    else:
      gLogger.error( "RPC.getStates() return error: %s" % result["Message"] )
      stat = [["Error happened on service side"]]
    callback["status"] = stat
# ##
    result = yield self.threadTask( RPC.getMinorStates )
    if result["OK"]:
      stat = []
      if len( result["Value"] ) > 0:
        for i in result["Value"]:
          stat.append( [i] )
      else:
        stat = [["Nothing to display"]]
    else:
      gLogger.error( "RPC.getMinorStates() return error: %s" % result["Message"] )
      stat = [["Error happened on service side"]]
    callback["minorstat"] = stat
# ##
    result = yield self.threadTask( RPC.getApplicationStates )
    if result["OK"]:
      app = []
      if len( result["Value"] ) > 0:
        for i in result["Value"]:
          app.append( [i] )
      else:
        app = [["Nothing to display"]]
    else:
      gLogger.error( "RPC.getApplicationstates() return error: %s" % result["Message"] )
      app = [["Error happened on service side"]]
    callback["app"] = app
# ##
    result = yield self.threadTask( RPC.getJobTypes )
    if result["OK"]:
      types = []
      if len( result["Value"] ) > 0:
        for i in result["Value"]:
          types.append( [i] )
      else:
        types = [["Nothing to display"]]
    else:
      gLogger.error( "RPC.getJobTypes() return error: %s" % result["Message"] )
      types = [["Error happened on service side"]]
    callback["types"] = types
# ##
    # groupProperty = credentials.getProperties(group)
    if user == "Anonymous":
      callback["owner"] = [["Insufficient rights"]]
    else:
      result = yield self.threadTask( RPC.getOwners )
      if result["OK"]:
        owner = []
        if len( result["Value"] ) > 0:
          for i in result["Value"]:
            owner.append( [str( i )] )
        else:
          owner = [["Nothing to display"]]
      elif 'NormalUser' in  sData['user']['properties']:
        owner = [[user]]
        callback["owner"] = owner
      else:
          gLogger.error( "RPC.getOwners() return error: %s" % result["Message"] )
          owner = [["Error happened on service side"]]
      callback["owner"] = owner
    
    result = yield self.threadTask( RPC.getOwnerGroup )
    if result['OK']:
      callback['OwnerGroup'] = [ [group] for group in result['Value']]  
    
    self.finish( callback )

  def _request( self ):
    self.pageNumber = 0
    self.numberOfJobs = 25
    self.globalSort = [["JobID", "DESC"]]

    req = {}
    
    if self.request.arguments.has_key( "limit" ) and len( self.request.arguments["limit"][0] ) > 0:
      self.numberOfJobs = int( self.request.arguments["limit"][0] )
      if self.request.arguments.has_key( "start" ) and len( self.request.arguments["start"][0] ) > 0:
        self.pageNumber = int( self.request.arguments["start"][0] )
      else:
        self.pageNumber = 0

    if "JobID" in self.request.arguments:
      jobids = list( json.loads( self.request.arguments[ 'JobID' ][-1] ) )
      if len( jobids ) > 0:
        req['JobID'] = jobids


    if "jobGroup" in self.request.arguments:
      prodids = list( json.loads( self.request.arguments[ 'jobGroup' ][-1] ) )
      if len( prodids ) > 0:
        req['JobGroup'] = prodids

    if "site" in self.request.arguments:
      sites = list( json.loads( self.request.arguments[ 'site' ][-1] ) )
      if len( sites ) > 0:
        req["Site"] = sites

    if "status" in self.request.arguments:
      status = list( json.loads( self.request.arguments[ 'status' ][-1] ) )
      if len( status ) > 0:
        req["Status"] = status

    if "minorStatus" in self.re