def tinder_http_post(server, selector, content_type, body):
    import httplib
    # now post it
    for i in range(0,5):
        try:
            h = httplib.HTTP(server)
            h.putrequest('POST', selector)
            h.putheader('content-type', content_type)
            h.putheader('content-length', str(len(body)))
            h.endheaders()
            h.send(body)
            errcode, errmsg, headers = h.getreply()
            #print errcode, errmsg, headers
            return (errcode,errmsg, headers, h.file)
        except:
            print "Error sending the report!"
            # try again
            pass

    # return some garbage
    return (-1, "unknown", "unknown", None)

def tinder_form_data(bound, dict, log):
    output = []
    # for each key in the dictionary
    for name in dict:
        assert dict[name]
        output.append( "--" + bound )
        output.append( 'Content-Disposition: form-data; name="%s"' % name )
        output.append( "" )
        output.append( dict[name] )
    if log:
        output.append( "--" + bound )
        output.append( 'Content-Disposition: form-data; name="log"; filename="log.txt"' )
        output.append( '' )
        output.append( log )
    output.append( '--' + bound + '--' )
    output.append( '' )

    return "\r\n".join(output)

def tinder_time_string():
    """
    Return the time as GMT
    """
    return ""

def tinder_format_http_post(d,status,log):
    """
    Format the Tinderbox HTTP post with the data needed
    for the tinderbox to be happy.
    """

    import random

    # the variables we will need to send on this form post
    variables =  {
        "tree"         : d.getVar('TINDER_TREE', True),
        "machine_name" : d.getVar('TINDER_MACHINE', True),
        "os"           : os.uname()[0],
        "os_version"   : os.uname()[2],
        "compiler"     : "gcc",
        "clobber"      : d.getVar('TINDER_CLOBBER', True) or "0",
        "srcdate"      : d.getVar('SRCDATE', True),
        "PN"           : d.getVar('PN', True),
        "PV"           : d.getVar('PV', True),
        "PR"           : d.getVar('PR', True),
        "FILE"         : d.getVar('FILE', True) or "N/A",
        "TARGETARCH"   : d.getVar('TARGET_ARCH', True),
        "TARGETFPU"    : d.getVar('TARGET_FPU', True) or "Unknown",
        "TARGETOS"     : d.getVar('TARGET_OS', True) or "Unknown",
        "MACHINE"      : d.getVar('MACHINE', True) or "Unknown",
        "DISTRO"       : d.getVar('DISTRO', True) or "Unknown",
        "zecke-rocks"  : "sure",
    }

    # optionally add the status
    if status:
        variables["status"] = str(status)

    # try to load the machine id
    # we only need on build_status.pl but sending it
    # always does not hurt
    try:
        f = file(d.getVar('TMPDIR',True)+'/tinder-machine.id', 'r')
        id = f.read()
        variables['machine_id'] = id
    except:
        pass

    # the boundary we will need
    boundary = "----------------------------------%d" % int(random.random()*1000000000000)

    # now format the body
    body = tinder_form_data( boundary, variables, log )

    return ("multipart/form-data; boundary=%s" % boundary),body


def tinder_build_start(d):
    """
    Inform the tinderbox that a build is starting. We do this
    by posting our name and tree to the build_start.pl script
    on the server.
    """

    # get the body and type
    content_type, body = tinder_format_http_post(d,None,None)
    server = d.getVar('TINDER_HOST', True )
    url    = d.getVar('TINDER_URL', True )

    selector = url + "/xml/build_start.pl"

    #print "selector %s and url %s" % (selector, url)

    # now post it
    errcode, errmsg, headers, h_file = tinder_http_post(server,selector,content_type, body)
    #print errcode, errmsg, headers
    report = h_file.read()

    # now let us find the machine id that was assigned to us
    search = "<machine id='"
    report = report[report.find(search)+len(search):]
    report = report[0:report.find("'")]

    bb.note("Machine ID assigned by tinderbox: %s" % report )

    # now we will need to save the machine number
    # we will override any previous numbers
    f = file(d.getVar('TMPDIR', True)+"/tinder-machine.id", 'w')
    f.write(report)


def tinder_send_http(d, status, _log):
    """
    Send this log as build status
    """

    # get the body and type
    server = d.getVar('TINDER_HOST', True)
    url    = d.getVar('TINDER_URL', True)

    selector = url + "/xml/build_status.pl"

    # now post it - in chunks of 10.000 charachters
    new_log = _log
    while len(new_log) > 0:
        content_type, body = tinder_format_http_post(d,status,new_log[0:18000])
        errcode, errmsg, headers, h_file = tinder_http_post(server,selector,content_type, body)
        #print errcode, errmsg, headers
        #print h.file.read()
        new_log = new_log[18000:]


def tinder_print_info(d):
    """
    Print the TinderBox Info
        Including informations of the BaseSystem and the Tree
        we use.
    """

    # get the local vars
    time    = tinder_time_string()
    ops     = os.uname()[0]
    version = os.uname()[2]
    url     = d.getVar( 'TINDER_URL' , True )
    tree    = d.getVar( 'TINDER_TREE', True )
    branch  = d.getVar( 'TINDER_BRANCH', True )
    srcdate = d.getVar( 'SRCDATE', True )
    machine = d.getVar( 'MACHINE', True )
    distro  = d.getVar( 'DISTRO', True )
    bbfiles = d.getVar( 'BBFILES', True )
    tarch   = d.getVar( 'TARGET_ARCH', True )
    fpu     = d.getVar( 'TARGET_FPU', True )
    oerev   = d.getVar( 'OE_REVISION', True ) or "unknown"

    # there is a bug with tipple quoted strings
    # i will work around but will fix the original
    # bug as well
    output = []
    output.append("== Tinderbox Info" )
    output.append("Time: %(time)s" )
    output.append("OS: %(ops)s" )
    output.append("%(version)s" )
    output.append("Compiler: gcc" )
    output.append("Tinderbox Client: 0.1" )
    output.append("Tinderbox Client Last Modified: yesterday" )
    output.append("Tinderbox Protocol: 0.1" )
    output.append("URL: %(url)s" )
    output.append("Tree: %(tree)s" )
    output.append("Config:" )
    output.append("branch = '%(branch)s'" )
    output.append("TARGET_ARCH = '%(tarch)s'" )
    output.append("TARGET_FPU = '%(fpu)s'" )
    output.append("SRCDATE = '%(srcdate)s'" )
    output.append("MACHINE = '%(machine)s'" )
    output.append("DISTRO = '%(distro)s'" )
    output.append("BBFILES = '%(bbfiles)s'" )
    output.append("OEREV = '%(oerev)s'" )
    output.append("== End Tinderbox Client Info" )

    # now create the real output
    return "\n".join(output) % vars()


def tinder_print_env():
    """
    Print the environment variables of this build
    """
    time_start = tinder_time_string()
    time_end   = tinder_time_string()

    # build the environment
    env = ""
    for var in os.environ:
        env += "%s=%s\n" % (var, os.environ[var])

    output = []
    output.append( "---> TINDERBOX RUNNING env %(time_start)s" )
    output.append( env )
    output.append( "<--- TINDERBOX FINISHED (SUCCESS) %(time_end)s" )

    return "\n".join(output) % vars()

def tinder_tinder_start(d, event):
    """
    PRINT the configuration of this build
    """

    time_start = tinder_time_string()
    config = tinder_print_info(d)
    #env    = tinder_print_env()
    time_end   = tinder_time_string()
    packages = " ".join( event.getPkgs() ) 

    output = []
    output.append( "---> TINDERBOX PRINTING CONFIGURATION %(time_start)s" )
    output.append( config )
    #output.append( env    )
    output.append( "<--- TINDERBOX FINISHED PRINTING CONFIGURATION %(time_end)s" )
    output.append( "---> TINDERBOX BUILDING '%(packages)s'" )
    output.append( "<--- TINDERBOX STARTING BUILD NOW" )

    output.append( "" )

    return "\n".join(output) % vars()

def tinder_do_tinder_report(event):
    """
    Report to the tinderbox:
        On the BuildStart we will inform the box directly
        On the other events we will write to the TINDER_LOG and
        when the Task is finished we will send the report.

    The above is not yet fully implemented. Currently we send
    information immediately. The caching/queuing needs to be
    implemented. Also sending more or less information is not
    implemented yet.

    We have two temporary files stored in the TMP directory. One file
    contains the assigned machine id for the tinderclient. This id gets
    assigned when we connect the box and start the build process the second
    file is used to workaround an EventHandler limitation. If BitBake is ran
    with the continue option we want the Build to fail even if we get the
    BuildCompleted Event. In this case we have to look up the status and
    send it instead of 100/success.
    """
    import glob

    # variables
    name = bb.event.getName(event)
    log  = ""
    status = 1
    # Check what we need to do Build* shows we start or are done
    if name == "BuildStarted":
        tinder_build_start(event.data)
        log = tinder_tinder_start(event.data,event)

        try:
            # truncate the tinder log file
            f = file(event.data.getVar('TINDER_LOG', True), 'w')
            f.write("")
            f.close()
        except:
            pass

        try:
            # write a status to the file. This is needed for the -k option
            # of BitBake
            g = file(event.data.getVar('TMPDIR', True)+"/tinder-status", 'w')
            g.write("")
            g.close()
        except IOError:
            pass

    # Append the Task-Log (compile,configure...) to the log file
    # we will send to the server
    if name == "TaskSucceeded" or name == "TaskFailed":
        log_file = glob.glob("%s/log.%s.*" % (event.data.getVar('T', True), event.task))

        if len(log_file) != 0:
            to_file  = event.data.getVar('TINDER_LOG', True)
            log     += "".join(open(log_file[0], 'r').readlines())

    # set the right 'HEADER'/Summary for the TinderBox
    if name == "TaskStarted":
        log += "---> TINDERBOX Task %s started\n" % event.task
    elif name == "TaskSucceeded":
        log += "<--- TINDERBOX Task %s done (SUCCESS)\n" % event.task
    elif name == "TaskFailed":
        log += "<--- TINDERBOX Task %s failed (FAILURE)\n" % event.task
    elif name == "PkgStarted":
        log += "---> TINDERBOX Package %s started\n" % event.data.getVar('PF', True)
    elif name == "PkgSucceeded":
        log += "<--- TINDERBOX Package %s done (SUCCESS)\n" % event.data.getVar('PF', True)
    elif name == "PkgFailed":
        if not event.data.getVar('TINDER_AUTOBUILD', True) == "0":
            build.exec_task('do_clean', event.data)
        log += "<--- TINDERBOX Package %s failed (FAILURE)\n" % event.data.getVar('PF', True)
        status = 200
        # remember the failure for the -k case
        h = file(event.data.getVar('TMPDIR', True)+"/tinder-status", 'w')
        h.write("200")
    elif name == "BuildCompleted":
        log += "Build Completed\n"
        status = 100
        # Check if we have a old status...
        try:
            h = file(event.data.getVar('TMPDIR',True)+'/tinder-status', 'r')
            status = int(h.read())
        except:
            pass

    elif name == "MultipleProviders":
        log += "---> TINDERBOX Multiple Providers\n"
        log += "multiple providers are available (%s);\n" % ", ".join(event.getCandidates())
        log += "consider defining PREFERRED_PROVIDER_%s\n" % event.getItem()
        log += "is runtime: %d\n" % event.isRuntime()
        log += "<--- TINDERBOX Multiple Providers\n"
    elif name == "NoProvider":
        log += "Error: No Provider for: %s\n" % event.getItem()
        log += "Error:Was Runtime: %d\n" % event.isRuntime()
        status = 200
        # remember the failure for the -k case
        h = file(event.data.getVar('TMPDIR', True)+"/tinder-status", 'w')
        h.write("200")

    # now post the log
    if len(log) == 0:
        return

    # for now we will use the http post method as it is the only one
    log_post_method = tinder_send_http
    log_post_method(event.data, status, log)


# we want to be an event handler
addhandler tinderclient_eventhandler
python tinderclient_eventhandler() {
    if e.data is None or bb.event.getName(e) == "MsgNote":
        return

    do_tinder_report = e.data.getVar('TINDER_REPORT', True)
    if do_tinder_report and do_tinder_report == "1":
        tinder_do_tinder_report(e)

    return
}
