#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Standardized types do not require authors to specify any control script as
# it can be generated on import. However when provided it will overwrite the
# default behaivior.


import sys
import subprocess
import re
import time

def build(ctx):
    # Add filenames
    allArgs = ['/usr/bin/make']

    # start subprocess in with work_path as cwd
    p = subprocess.Popen(allArgs, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=ctx.work_path)
    msgs,errs = p.communicate()
    retval = p.wait()

    errs = errs.decode("utf-8")
    msgs = msgs.decode("utf-8")

    return retval, errs, msgs


def execute(ctx):
    allArgs = ("/usr/bin/docker run -h oer-worker --user 1001:65534 --rm -v /data/run/jobs/%s/:/data/ --network none kunkel/oer-worker /data/execute.sh" % ctx.id).split(" ")
    print(" ".join(allArgs), file=sys.stderr)

    # start subprocess in with work_path as cwd
    p = subprocess.Popen(allArgs, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=ctx.work_path)
    timeout = 1
    poll_period = 0.1
    p.poll()
    while p.returncode is None and timeout > 0:
        time.sleep(poll_period)
        timeout -= poll_period
        p.poll()
    if timeout <= 0:
        p.kill() # timed out

    msgs,errs = p.communicate()
    retval = p.wait()

    errs = errs.decode("utf-8")
    msgs = msgs.decode("utf-8")
    
    if timeout <= 0:
      errs += "\nKilled after timeout!\n"

    return retval, errs, msgs


def grade(ctx):
    #print("GRADING!!", file=sys.stderr)

    # if build failed, return early and set grade to FAIL
    if ctx.build_result[0] != 0:
        return 'FAIL'
    allArgs = ("/usr/bin/docker run -h oer-worker --user 1001:65534 --rm -v /data/run/jobs/%s/:/data/ --network none kunkel/oer-worker /data/test.sh" % ctx.id).split(" ")
    print(" ".join(allArgs), file=sys.stderr)

    # start subprocess in with work_path as cwd
    p = subprocess.Popen(allArgs, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=ctx.work_path)
    timeout = 1
    poll_period = 0.1
    p.poll()
    while p.returncode is None and timeout > 0:
        time.sleep(poll_period)
        timeout -= poll_period
        p.poll()
    if timeout <= 0:
        p.kill() # timed out

    msgs,errs = p.communicate()
    retval = p.wait()

    errs = errs.decode("utf-8")
    msgs = msgs.decode("utf-8")


    ctx.execute_result = (retval, errs, msgs)

    print(ctx.execute_result, file=sys.stderr)

    if re.match('FAIL', msgs, re.MULTILINE) != None:
        return 'FAIL'
    else:
        return 'PASS'


def response(ctx):
    if ctx.build_result[0] != 0:
        output = ctx.build_result[1]
    else:
        output = ctx.execute_result[2] + "\n" + ctx.execute_result[1]

    grade = ctx.grade_result
    msg = ""
    return {'output': output, 'grade': grade, 'msg': msg, 'data': None}
