#!/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.
#


###############################################################################
## This file is being obsoleted by qmf/console.py
###############################################################################

from __future__ import absolute_import
from __future__ import print_function
import qpid
import re
import socket
import struct
import os
import platform
import locale
from qpid.connection import Timeout
from qpid.management import managementChannel, managementClient
from threading       import Lock
from .disp           import Display
from shlex           import split
from qpid.connection import Connection
from qpid.util       import connect

try:
  long
except NameError:
  long = int

class Broker:
  def __init__ (self, text):
    rex = re.compile(r"""
    # [   <user>  [   / <password> ] @]  <host>  [   :<port>   ]
    ^ (?: ([^/]*) (?: / ([^@]*)   )? @)? ([^:]+) (?: :([0-9]+))?$""", re.X)
    match = rex.match(text)
    if not match: raise ValueError("'%s' is not a valid broker url" % (text))
    user, password, host, port = match.groups()

    if port: self.port = int(port)
    else: self.port = 5672
    for addr in socket.getaddrinfo(host, self.port):
      if addr[1] == socket.AF_INET:
        self.host = addr[4][0]
    self.username = user or "guest"
    self.password = password or "guest"

  def name (self):
    return self.host + ":" + str (self.port)

class ManagementData:

  #
  # Data Structure:
  #
  # Please note that this data structure holds only the most recent
  # configuration and instrumentation data for each object.  It does
  # not hold the detailed historical data that is sent from the broker.
  # The only historical data it keeps are the high and low watermarks
  # for hi-lo statistics.
  #
  #    tables        :== {class-key}
  #                        {<obj-id>}
  #                          (timestamp, config-record, inst-record)
  #    class-key     :== (<package-name>, <class-name>, <class-hash>)
  #    timestamp     :== (<last-interval-time>, <create-time>, <delete-time>)
  #    config-record :== [element]
  #    inst-record   :== [element]
  #    element       :== (<element-name>, <element-value>)
  #

  def registerObjId (self, objId):
    if not objId.index() in self.idBackMap:
      self.idBackMap[objId.index()] = self.nextId
      self.idMap[self.nextId] = objId
      self.nextId += 1

  def displayObjId (self, objIdIndex):
    if objIdIndex in self.idBackMap:
      return self.idBackMap[objIdIndex]
    else:
      return 0

  def rawObjId (self, displayId):
    if displayId in self.idMap:
      return self.idMap[displayId]
    else:
      return None

  def displayClassName (self, cls):
    (packageName, className, hash) = cls
    rev = self.schema[cls][4]
    if rev == 0:
      suffix = ""
    else:
      suffix = ".%d" % rev
    return packageName + ":" + className + suffix

  def dataHandler (self, context, className, list, timestamps):
    """ Callback for configuration and instrumentation data updates """
    self.lock.acquire ()
    try:
      # If this class has not been seen before, create an empty dictionary to
      # hold objects of this class
      if className not in self.tables:
        self.tables[className] = {}

      # Register the ID so a more friendly presentation can be displayed
      objId = list[0][1]
      oidx  = objId.index()
      self.registerObjId (objId)

      # If this object hasn't been seen before, create a new object record with
      # the timestamps and empty lists for configuration and instrumentation data.
      if oidx not in self.tables[className]:
        self.tables[className][oidx] = (timestamps, [], [])

      (unused, oldConf, oldInst) = self.tables[className][oidx]

      # For config updates, simply replace old config list with the new one.
      if   context == 0: #config
        self.tables[className][oidx] = (timestamps, list, oldInst)

      # For instrumentation updates, carry the minimum and maximum values for
      # "hi-lo" stats forward.
      elif context == 1: #inst
        if len (oldInst) == 0:
          newInst = list
        else:
          newInst = []
          for idx in range (len (list)):
            (key, value) = list[idx]
            if key.find ("High") == len (key) - 4:
              if oldInst[idx][1] > value:
                value = oldInst[idx][1]
            if key.find ("Low") == len (key) - 3:
              if oldInst[idx][1] < value:
                value = oldInst[idx][1]
            newInst.append ((key, value))
        self.tables[className][oidx] = (timestamps, oldConf, newInst)

    finally:
      self.lock.release ()

  def ctrlHandler (self, context, op, data):
    if op == self.mclient.CTRL_BROKER_INFO:
      pass
    elif op == self.mclient.CTRL_HEARTBEAT:
      pass

  def configHandler (self, context, className, list, timestamps):
    self.dataHandler (0, className, list, timestamps)

  def instHandler (self, context, className, list, timestamps):
    self.dataHandler (1, className, list, timestamps)

  def methodReply (self, broker, sequence, status, sText, args):
    """ Callback for method-reply messages """
    self.lock.acquire ()
    try:
      line = "Call Result: " + self.methodsPending[sequence] + \
             "  " + str (status) + " (" + sText + ")"
      print(line, args)
      del self.methodsPending[sequence]
    finally:
      self.lock.release ()

  def closeHandler (self, context, reason):
    if self.operational:
      print("Connection to broker lost:", reason)
    self.operational = False
    if self.cli != None:
      self.cli.setPromptMessage ("Broker Disconnected")

  def schemaHandler (self, context, classKey, configs, insts, methods, events):
    """ Callback for schema updates """
    if classKey not in self.schema:
      schemaRev = 0
      for key in self.schema:
        if classKey[0] == key[0] and classKey[1] == key[1]:
          schemaRev += 1
      self.schema[classKey] = (configs, insts, methods, events, schemaRev)

  def setCli (self, cliobj):
    self.cli = cliobj

  def __init__ (self, disp, host, username="guest", password="guest"):
    self.lock           = Lock ()
    self.tables         = {}
    self.schema         = {}
    self.bootSequence   = 0
    self.operational    = False
    self.disp           = disp
    self.cli            = None
    self.lastUnit       = None
    self.methodSeq      = 1
    self.methodsPending = {}
    self.sessionId      = "%s.%d" % (platform.uname()[1], os.getpid())

    self.broker = Broker (host)
    sock = connect (self.broker.host, self.broker.port)
    oldTimeout = sock.gettimeout()
    sock.settimeout(10)
    self.conn   = Connection (sock,
                              username=self.broker.username, password=self.broker.password)
    def aborted():
      raise Timeout("Waiting for connection to be established with broker")
    oldAborted = self.conn.aborted
    self.conn.aborted = aborted

    self.conn.start ()

    sock.settimeout(oldTimeout)
    self.conn.aborted = oldAborted

    self.mclient = managementClient ("unused", self.ctrlHandler, self.configHandler,
                                     self.instHandler, self.methodReply, self.closeHandler)
    self.mclient.schemaListener (self.schemaHandler)
    self.mch = self.mclient.addChannel (self.conn.session(self.sessionId))
    self.operational = True
    self.idMap = {}
    self.idBackMap = {}
    self.nextId = 101

  def close (self):
    pass

  def refName (self, oid):
    if oid == None:
      return "NULL"
    return str (self.displayObjId (oid.index()))

  def valueDisplay (self, classKey, key, value):
    if value == None:
      return "<NULL>"
    for kind in range (2):
      schema = self.schema[classKey][kind]
      for item in schema:
        if item[0] == key:
          typecode = item[1]
          unit     = item[2]
          if (typecode >= 1 and typecode <= 5) or typecode == 12 or typecode == 13 or \
                (typecode >= 16 and typecode <= 19):
            if unit == None or unit == self.lastUnit:
              return str (value)
            else:
              self.lastUnit = unit
              suffix = ""
              if value != 1:
                suffix = "s"
              return str (value) + " " + unit + suffix
          elif typecode == 6 or typecode == 7: # strings
            return value
          elif typecode == 8:
            if value == 0:
              return "--"
            return self.disp.timestamp (value)
          elif typecode == 9:
            return str (value)
          elif typecode == 10:
            return self.refName (value)
          elif typecode == 11:
            if value == 0:
              return "False"
            else:
              return "True"
          elif typecode == 14:
            return str (value)
          elif typecode == 15:
            return str (value)
    return "*type-error*"

  def getObjIndex (self, classKey, config):
    """ Concatenate the values from index columns to form a unique object name """
    result = ""
    schemaConfig = self.schema[classKey][0]
    for item in schemaConfig:
      if item[5] == 1 and item[0] != "id":
        if result != "":
          result = result + "."
        for key,val in config:
          if key == item[0]:
            result = result + self.valueDisplay (classKey, key, val)
    return result

  def getClassKey (self, className):
    delimPos = className.find(":")
    if delimPos == -1:
      schemaRev = 0
      delim = className.find(".")
      if delim != -1:
        schemaRev = int(className[delim + 1:])
        name      = className[0:delim]
      else:
        name = className
      for key in self.schema:
        if key[1] == name and self.schema[key][4] == schemaRev:
          return key
    else:
      package   = className[0:delimPos]
      name      = className[delimPos + 1:]
      schemaRev = 0
      delim = name.find(".")
      if delim != -1:
        schemaRev = int(name[delim + 1:])
        name      = name[0:delim]
      for key in self.schema:
        if key[0] == package and key[1] == name:
          if self.schema[key][4] == schemaRev:
            return key
    return None

  def classCompletions (self, prefix):
    """ Provide a list of candidate class names for command completion """
    self.lock.acquire ()
    complist = []
    try:
      for name in self.tables:
        if name.find (prefix) == 0:
          complist.append (name)
    finally:
      self.lock.release ()
    return complist

  def typeName (self, typecode):
    """ Convert type-codes to printable strings """
    if   typecode == 1:
      return "uint8"
    elif typecode == 2:
      return "uint16"
    elif typecode == 3:
      return "uint32"
    elif typecode == 4:
      return "uint64"
    elif typecode == 5:
      return "bool"
    elif typecode == 6:
      return "short-string"
    elif typecode == 7:
      return "long-string"
    elif typecode == 8:
      return "abs-time"
    elif typecode == 9:
      return "delta-time"
    elif typecode == 10:
      return "reference"
    elif typecode == 11:
      return "boolean"
    elif typecode == 12:
      return "float"
    elif typecode == 13:
      return "double"
    elif typecode == 14:
      return "uuid"
    elif typecode == 15:
      return "field-table"
    elif typecode == 16:
      return "int8"
    elif typecode == 17:
      return "int16"
    elif typecode == 18:
      return "int32"
    elif typecode == 19:
      return "int64"
    elif typecode == 20:
      return "object"
    elif typecode == 21:
      return "list"
    elif typecode == 22:
      return "array"      
    else:
      raise ValueError ("Invalid type code: %d" % typecode)

  def accessName (self, code):
    """ Convert element access codes to printable strings """
    if code == 1:
      return "ReadCreate"
    elif code == 2:
      return "ReadWrite"
    elif code == 3:
      return "ReadOnly"
    else:
      raise ValueError ("Invalid access code: %d" %code)

  def notNone (self, text):
    if text == None:
      return ""
    else:
      return text

  def isOid (self, id):
    for char in str (id):
      if not char.isdigit () and not char == '-':
        return False
    return True

  def listOfIds (self, classKey, tokens):
    """ Generate a tuple of object ids for a classname based on command tokens. """
    list = []
    if len(tokens) == 0 or tokens[0] == "all":
      for id in self.tables[classKey]:
        list.append (self.displayObjId (id))

    elif tokens[0] == "active":
      for id in self.tables[classKey]:
        if self.tables[classKey][id][0][2] == 0:
          list.append (self.displayObjId (id))

    else:
      for token in tokens:
        if self.isOid (token):
          if token.find ("-") != -1:
            ids = token.split("-", 2)
            for id in range (int (ids[0]), int (ids[1]) + 1):
              if self.getClassForId (self.rawObjId (long (id))) == classKey:
                list.append (id)
          else:
            list.append (int(token))

    list.sort ()
    result = ()
    for item in list:
      result = result + (item,)
    return result

  def listClasses (self):
    """ Generate a display of the list of classes """
    self.lock.acquire ()
    try:
      rows = []
      sorted = self.tables.keys ()
      sorted.sort ()
      for name in sorted:
        active  = 0
        deleted = 0
        for record in self.tables[name]:
          isdel = False
          ts    = self.tables[name][record][0]
          if ts[2] > 0:
            isdel = True
          if isdel:
            deleted = deleted + 1
          else:
            active = active + 1
        rows.append ((self.displayClassName (name), active, deleted))
      if len (rows) != 0:
        self.disp.table ("Management Object Types:",
                         ("ObjectType", "Active", "Deleted"), rows)
      else:
        print("Waiting for next periodic update")
    finally:
      self.lock.release ()

  def listObjects (self, tokens):
    """ Generate a display of a list of objects in a class """
    if len(tokens) == 0:
      print("Error - No class name provided")
      return

    self.lock.acquire ()
    try:
      classKey = self.getClassKey (tokens[0])
      if classKey == None:
        print(("Object type %s not known" % tokens[0]))
      else:
        rows = []
        if classKey in self.tables:
          ids = self.listOfIds(classKey, tokens[1:])
          for objId in ids:
            (ts, config, inst) = self.tables[classKey][self.rawObjId(objId).index()]
            createTime  = self.disp.timestamp (ts[1])
            destroyTime = "-"
            if ts[2] > 0:
              destroyTime = self.disp.timestamp (ts[2])
            objIndex = self.getObjIndex (classKey, config)
            row = (objId, createTime, destroyTime, objIndex)
            rows.append (row)
          self.disp.table ("Objects of type %s" % self.displayClassName(classKey),
                           ("ID", "Created", "Destroyed", "Index"),
                           rows)
    finally:
      self.lock.release ()

  def showObjects (self, tokens):
    """ Generate a display of object data for a particular class """
    self.lock.acquire ()
    try:
      self.lastUnit = None
      if self.isOid (tokens[0]):
        if tokens[0].find ("-") != -1:
          rootId = int (tokens[0][0:tokens[0].find ("-")])
        else:
          rootId = int (tokens[0])

        classKey  = self.getClassForId (self.rawObjId (rootId))
        remaining = tokens
        if classKey == None:
          print("Id not known: %d" % int (tokens[0]))
          raise ValueError ()
      else:
        classKey  = self.getClassKey (tokens[0])
        remaining = tokens[1:]
        if classKey not in self.tables:
          print("Class not known: %s" % tokens[0])
          raise ValueError ()

      userIds = self.listOfIds (classKey, remaining)
      if len (userIds) == 0:
        print("No object IDs supplied")
        raise ValueError ()

      ids = []
      for id in userIds:
        if self.getClassForId (self.rawObjId (long (id))) == classKey:
          ids.append (self.rawObjId (long (id)))

      rows = []
      timestamp = None
      config = self.tables[classKey][ids[0].index()][1]
      for eIdx in range (len (config)):
        key = config[eIdx][0]
        if key != "id":
          row   = ("property", key)
          for id in ids:
            if timestamp == None or \
               timestamp < self.tables[classKey][id.index()][0][0]:
              timestamp = self.tables[classKey][id.index()][0][0]
            (key, value) = self.tables[classKey][id.index()][1][eIdx]
            row = row + (self.valueDisplay (classKey, key, value),)
          rows.append (row)

      inst = self.tables[classKey][ids[0].index()][2]
      for eIdx in range (len (inst)):
        key = inst[eIdx][0]
        if key != "id":
          row = ("statistic", key)
          for id in ids:
            (key, value) = self.tables[classKey][id.index()][2][eIdx]
            row = row + (self.valueDisplay (classKey, key, value),)
          rows.append (row)

      titleRow = ("Type", "Element")
      for id in ids:
        titleRow = titleRow + (self.refName(id),)
      caption = "Object of type %s:" % self.displayClassName(classKey)
      if timestamp != None:
        caption = caption + " (last sample time: " + self.disp.timestamp (timestamp) + ")"
      self.disp.table (caption, titleRow, rows)

    except:
      pass
    self.lock.release ()

  def schemaSummary (self):
    """ Generate a display of the list of classes in the schema """
    self.lock.acquire ()
    try:
      rows = []
      sorted = self.schema.keys ()
      sorted.sort ()
      for classKey in sorted:
        tuple = self.schema[classKey]
        row = (self.displayClassName(classKey), len (tuple[0]), len (tuple[1]),
               len (tuple[2]))
        rows.append (row)
      self.disp.table ("Classes in Schema:",
                       ("Class", "Properties", "Statistics", "Methods"),
                       rows)
    finally:
      self.lock.release ()

  def schemaTable (self, className):
    """ Generate a display of details of the schema of a particular class """
    self.lock.acquire ()
    try:
      classKey = self.getClassKey (className)
      if classKey == None:
        print(("Class name %s not known" % className))
        raise ValueError ()

      rows = []
      schemaRev =  self.schema[classKey][4]
      for config in self.schema[classKey][0]:
        name     = config[0]
        if name != "id":
          typename = self.typeName(config[1])
          unit     = self.notNone (config[2])
          desc     = self.notNone (config[3])
          access   = self.accessName (config[4])
          extra    = ""
          if config[5] == 1:
            extra += "index "
          if config[6] != None:
            extra += "Min: " + str(config[6]) + " "
          if config[7] != None:
            extra += "Max: " + str(config[7]) + " "
          if config[8] != None:
            extra += "MaxLen: " + str(config[8]) + " "
          if config[9] == 1:
            extra += "optional "
          rows.append ((name, typename, unit, access, extra, desc))
        
      for config in self.schema[classKey][1]:
        name     = config[0]
        if name != "id":
          typename = self.typeName(config[1])
          unit     = self.notNone (config[2])
          desc     = self.notNone (config[3])
          rows.append ((name, typename, unit, "", "", desc))

      titles = ("Element", "Type", "Unit", "Access", "Notes", "Description")
      self.disp.table ("Schema for class '%s':" % self.displayClassName(classKey), titles, rows)

      for mname in self.schema[classKey][2]:
        (mdesc, args) = self.schema[classKey][2][mname]
        caption = "\nMethod '%s' %s" % (mname, self.notNone (mdesc))
        rows = []
        for arg in args:
          name     = arg[0]
          typename = self.typeName (arg[1])
          dir      = arg[2]
          unit     = self.notNone (arg[3])
          desc     = self.notNone (arg[4])
          extra    = ""
          if arg[5] != None:
            extra = extra + "Min: " + str (arg[5])
          if arg[6] != None:
            extra = extra + "Max: " + str (arg[6])
          if arg[7] != None:
            extra = extra + "MaxLen: " + str (arg[7])
          if arg[8] != None:
            extra = extra + "Default: " + str (arg[8])
          rows.append ((name, typename, dir, unit, extra, desc))
        titles = ("Argument", "Type", "Direction", "Unit", "Notes", "Description")
        self.disp.table (caption, titles, rows)

    except Exception as e:
      pass
    self.lock.release ()

  def getClassForId (self, objId):
    """ Given an object ID, return the class key for the referenced object """
    for classKey in self.tables:
      if objId.index() in self.tables[classKey]:
        return classKey
    return None

  def callMethod (self, userOid, methodName, args):
    self.lock.acquire ()
    methodOk = True
    try:
      classKey = self.getClassForId (self.rawObjId (userOid))
      if classKey == None:
        raise ValueError ()

      if methodName not in self.schema[classKey][2]:
        print("Method '%s' not valid for class '%s'" % (methodName, self.displayClassName(classKey)))
        raise ValueError ()

      schemaMethod = self.schema[classKey][2][methodName]
      count = 0
      for arg in range(len(schemaMethod[1])):
        if schemaMethod[1][arg][2].find("I") != -1:
          count += 1
      if len (args) != count:
        print("Wrong number of method args: Need %d, Got %d" % (count, len (args)))
        raise ValueError ()

      namedArgs = {}
      idx = 0
      for arg in range(len(schemaMethod[1])):
        if schemaMethod[1][arg][2].find("I") != -1:
          namedArgs[schemaMethod[1][arg][0]] = args[idx]
          idx += 1

      self.methodSeq = self.methodSeq + 1
      self.methodsPending[self.methodSeq] = methodName
    except Exception as e:
      methodOk = False
    self.lock.release ()
    if methodOk:
#      try:
        self.mclient.callMethod (self.mch, self.methodSeq, self.rawObjId (userOid), classKey,
                                 methodName, namedArgs)
#      except ValueError, e:
#        print "Error invoking method:", e

  def makeIdRow (self, displayId):
    if displayId in self.idMap:
      objId = self.idMap[displayId]
    else:
      return None
    if objId.getFlags() == 0:
      flags = ""
    else:
      flags = str(objId.getFlags())
    seq = objId.getSequence()
    if seq == 0:
      seqText = "<durable>"
    else:
      seqText = str(seq)
    return (displayId, flags, seqText, objId.getBroker(), objId.getBank(), hex(objId.getObject()))

  def listIds (self, select):
    rows = []
    if select == 0:
      sorted = self.idMap.keys()
      sorted.sort()
      for displayId in sorted:
        row = self.makeIdRow (displayId)
        rows.append(row)
    else:
      row = self.makeIdRow (select)
      if row == None:
        print("Display Id %d not known" % select)
        return
      rows.append(row)
    self.disp.table("Translation of Display IDs:",
                    ("DisplayID", "Flags", "BootSequence", "Broker", "Bank", "Object"),
                    rows)

  def do_list (self, data):
    tokens = data.split ()
    if len (tokens) == 0:
      self.listClasses ()
    else:
      self.listObjects (tokens)

  def do_show (self, data):
    tokens = data.split ()
    self.showObjects (tokens)

  def do_schema (self, data):
    if data == "":
      self.schemaSummary ()
    else:
      self.schemaTable (data)

  def do_call (self, data):
    encTokens = data.split ()
    try:
      tokens = [a.decode(locale.getpreferredencoding()) for a in encArgs]
    except:
      tokens = encTokens
    if len (tokens) < 2:
      print("Not enough arguments supplied")
      return
    
    displayId  = long (tokens[0])
    methodName = tokens[1]
    args       = tokens[2:]
    self.callMethod (displayId, methodName, args)

  def do_id (self, data):
    if data == "":
      select = 0
    else:
      select = int(data)
    self.listIds(select)

  def do_exit (self):
    self.mclient.removeChannel (self.mch)
