import os, time
import whatap.util.process_util as process_util
from whatap.util.date_util import DateUtil as date_util
import whatap.util.thread_util as thread_util
import whatap.util.logging_util as logging_util
import whatap.agent.conf.configure as config
import whatap.agent.secure.security_master as secure
import whatap.pack.tagcount_pack as tagcount_pack
import whatap.agent.data.data_pack as data
from StringIO import StringIO


def check():
    pass

def testRun():
    import whatap.agent.conf.configure as config
    m= config.GetConfig().AgentlessItems
    if not m:
        return

    prefix = config.entrypoint_path
    for k, item in m.items():
        # logging_util.debug("testRun ", prefix, config.ScriptPath, item.script)
        check(item, os.path.join(prefix, config.ScriptPath, item.script), console_output=True)


class NameValuePair (object):
    def __init__(self, name = None, value=None):
        self.name = name
        self.value = value

class ClockValuePair (object):
    def __init__(self, clock = None, value= None):
        self.clock = clock
        self.value = value

class SimpleFloatMap(dict):
    def __init__(self):
        super(SimpleFloatMap, self).__init__()

class SimpleStringMap(dict):
    def __init__(self):
        super(SimpleStringMap, self).__init__()

class SimpleClockValueMap(dict):
    def __init__(self):
        super(SimpleClockValueMap, self).__init__()

#type SimpleFloatMap map[string]*map[string]float64
#type SimpleStringMap map[string][]NameValuePair
#type SimpleClockValueMap map[string]*ClockValuePair

def check(item , script , console_output=False) :
    logging_util.debug("check step -1 ", item.uid, item.gid , script)
    mapvalues = {}
    metavalues = {}
    if console_output:
        print('executing ', script ,' as uid:', item.uid, ' gid:', item.gid)
    exitcode, output = process_util.executeCmdEx(script, uid= item.uid, gid= item.gid)
    print('exitcode ', exitcode)
    if console_output:
        print(output)
    scanner = StringIO(output)
    for line in scanner.readlines():
        words = line.split()
        if console_output:
            print(words)
        if len(words) < 4 :
            continue

        datatype = words[0]
        instance = words[1]
        name = words[2]

        logging_util.debug("check step -2 ", words)
        # logging_util.debug("check step -2 ", id(metavalues), metavalues)
        if "M" == datatype or "m" == datatype :
            # logging_util.debug("check step -2.1 ", id(metavalues), metavalues)
            metaValue = " ".join(words[3:])
            # logging_util.debug("check step -2.2 ", id(metavalues), metavalues)
            if instance in metavalues:
                # logging_util.debug("check step -2.3 ", id(metavalues), metavalues)
                v = metavalues[instance]
                # logging_util.debug("check step -2.4 ", id(metavalues), metavalues)
                v.append(NameValuePair(name=name, value=metaValue))

            else:
                # logging_util.debug("check step -2.6 ", id(metavalues), metavalues)
                metavalues[instance] = [ NameValuePair(name= name, value= metaValue)]
                # logging_util.debug("check step -2.7 ", id(metavalues), metavalues)
        elif "H" == datatype or "h" == datatype:
            v = float(words[3])

            if instance not in  mapvalues:
                mapvalues[instance] = {}

            instValue = mapvalues[instance]
            instValue[name] = v
        # logging_util.debug("check step -3 ", id(metavalues), metavalues)

    return mapvalues, metavalues, 0


def start():
    thread_util.asyncLoop(_process, 30)


def _process():
    global concurrent
    m = {}
    m.update(config.GetConfig().AgentlessItems)
    logging_util.debug("checkmain._process step -1", m)
    if not m:
        return
    # logging_util.debug("checkmain._process step -2")
    secu = secure.GetSecurityMaster()
    now = date_util.now()

    def probe(pitem):
        logging_util.debug("_process probe ", item, config.entrypoint_path, config.ScriptPath, pitem.script)
        mapvalues, metavalues, _ = check(pitem, os.path.join(config.entrypoint_path, config.ScriptPath, pitem.script))

        logging_util.debug("_process step -5", metavalues)
        for inst, nameNvalues in mapvalues.items():
            p = tagcount_pack.TagCountPack()
            p.category = pitem.script.replace("/", "_").replace(".", "_")
            p.pcode = secu.pcode
            p.oid = secu.oid
            p.time = now
            for f, fvalue in nameNvalues.items():
                p.fields.putFloat(f, fvalue)
            p.tags.putString('inst', inst)
            if inst in metavalues:
                for nameNvalue in metavalues[inst]:
                    p.tags.putString(nameNvalue.name, nameNvalue.value)
                    # panicutil.Debug("_process step -5.0.2  ", nameNvalue.Name, nameNvalue.Value)
            # // panicutil.Debug("_process step -5.1 sending ", item.Script)
            logging_util.debug("checkmain._process step -3", p)
            data.SendHide(p)

    concurrent = 0
    prefix = config.entrypoint_path
    threads = []
    for item in m.values():
        # logging_util.debug("checkmain._process step -3")
        while concurrent >= config.GetConfig().AgentlessConcurrent:
            while threads:
                t = threads.pop()
                t.join()

        # logging_util.debug("checkmain._process step -4")
        concurrent +=1
        t = thread_util.async(probe, item)
        threads.append(t)
    while threads:
        t = threads.pop()
        t.join()
