import subprocess, shlex
import time, os
from StringIO import StringIO
import whatap.util.logging_util as logging_util
import threading, signal

def executeCmd(command='getconf CLK_TCK'):
    process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    buf = StringIO()
    while True:
        output = process.stdout.readline()
        if output == '' and process.poll() is not None:
            break
        buf.write(output)

    return buf.getvalue()

def executeCmdEx(command=None, uid=None, gid= None):
    if uid and gid:
        def preexec_fn():
            os.setgid(uid)
            os.setuid(gid)
        process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn= preexec_fn)
    else:
        process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    buf = StringIO()
    while True:
        output = process.stdout.readline()
        return_code = process.poll()
        if output == '' and return_code is not None:
            break
        buf.write(output)

    return return_code, buf.getvalue()

def executeCommandSimple(command=[], output= None):
    process = subprocess.Popen(command, stdout=output, stderr=output)
    return process

def executeCommandShell(command):
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    stdout, _ = process.communicate()

    return stdout.decode('utf-8').strip()

def executeCommandShellWithTimeout(command, timeout = 5):
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=os.setsid)

    stdout = [None]

    def target():
        stdout[0], _ = process.communicate()

    thread = threading.Thread(target=target)
    thread.start()

    thread.join(timeout)
    if thread.is_alive():
        logging_util.error("excute command timeout error : ", command)
        os.killpg(process.pid, signal.SIGKILL)
        thread.join(timeout)
        if thread.is_alive():
            logging_util.error("excute command kill fail : ", command)
            thread.join()
        return ""

    if stdout[0] == None:
        logging_util.error("excute command runtime error : ", command, process.returncode)
        return ""

    return stdout[0].decode('utf-8', 'replace').strip()


def initPollCommand():
    #kill old poll process pid
    pass

# TODO pid manager 
def pollCommand(command):
    process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn = os.setsid)

    return process



def getSimpleDict(command=None):
    started=time.time()*1000
    process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
    result = {}
    while True:
        output = process.stdout.readline().strip()
        #print 'getVmStat', output
        if not output and process.poll() is not None:
            break
        if output:
            #print 'getVmStat', output
            k, v = output.split()
            result[k] = v

    return result

def fixByteUnit(src):
    unit = {'k': 1024,'m': 1024*1024, 'g': 1024*1024*1024, 't': 1024*1024*1024*1024}
    try:
        src = int(float(src))
        return src
    except ValueError, e:
        src = int(float(src[:-1])) * unit[src[-1].lower()]

        return src


