# Path: judge/models.py
# class Coder(models.Model):
#     user = models.OneToOneField(User)
#     link = models.URLField()
#     score = models.DecimalField(default = 0, decimal_places = 3, max_digits = 100)
#     rank = models.IntegerField(default = -1)
#     problems_tried = models.ForeignKey('Problem', null = True, related_name = "problems_tried")
#     problems_ac = models.ForeignKey('Problem', null = True, related_name = "problems_ac")
# 
#     def __unicode__(self):
#         return self.user.username
# 
# class Submission(models.Model):
#     STATUSES = (
#                 ("NT", "Not tested"),
#                 ("CE", "Compile Error"),
#                 ("TL", "Time Limit Exceeded"),
#                 ("RE", "Runtime Error"),
#                 ("AC", "Accepted")
#                 )
#     submitter = models.ForeignKey(Coder, null = True)
#     problem = models.ForeignKey(Problem, default = None, null = True)
#     status = models.CharField(max_length = 2, default = "NT", choices = STATUSES)
#     lang = models.CharField(max_length = 4, default = "C", choices = LANGUAGES)
#     code = models.TextField(default="")
#     created = models.DateTimeField(auto_now_add=True)
#     private = models.BooleanField(default = True)
# 
# class Problem(models.Model):
#     # Problem name (example: life, the universe and everything)
#     name = models.CharField(max_length=255)
#     # Problem code (example: TEST)
#     code = models.CharField(max_length=20, unique = True)
#     # Problem link (example: poj.com/problems/TEST)
#     link = models.URLField()
#     # Problem statement
#     statement = models.TextField()
# 
#     num_submissions = models.IntegerField(default = 0) # number of submissions
#     num_ac = models.IntegerField(default = 0)     # number of accepted submissions
#     num_wa = models.IntegerField(default = 0)          # number of wrong answers
#     num_re = models.IntegerField(default = 0)          # number of runtime errors
#     num_tle = models.IntegerField(default = 0)         # number of tles
#     num_ce = models.IntegerField(default = 0)
#     date_added = models.DateTimeField(auto_now_add = True) # When added
#     time_limit = models.IntegerField(default=1)         # Time Limit
#     source = models.CharField(max_length=255)
#     num_tests = models.IntegerField(default = 1)
# 
#     author = models.ForeignKey('Coder', null = True)
# 
#     def __unicode__(self):
#         return self.code
# 
# class TestCase(models.Model):
#     problem = models.ForeignKey(Problem)
#     input_file = models.FileField(upload_to=in_upload_path)
#     output_file = models.FileField(upload_to=out_upload_path)
# 
#     def __unicode__(self):
#         return self.problem.code


from celery.decorators import task
from judge.models import Coder, Submission, Problem, TestCase
import subprocess
import os
    cur_problem = submission.problem
    cur_problem.num_submissions += 1
    tc = TestCase.objects.get(problem = cur_problem)
    ## this is real spaghetti code written in 2 hours
    # input_filename and output_filename only contain the file names such as 1.in, 2.out etc
    # tc.input_file.name on the other hand contains testcases/ (example: testcases/1.in)
    input_filename = tc.input_file.name.split("/")[1]
    output_filename = tc.output_file.name.split("/")[1]
    print("input = {}, output = {}".format(input_filename, output_filename))


    # first create a new docker container of the image poj with memory limit 256M so
    # user code does not kill the server
    container_id = subprocess.check_output(["docker", "run", "-it", "-m","256M","-d", "poj"])
    # decode bytestring to utf-8 and remove the last newline from docker output
    container_id = container_id.decode('utf-8')
    print(container_id)
    container_id = container_id[:len(container_id)-1]

    # this list can be appended to any command to make it run in container_id
    docker_lst  = ["docker", "exec", container_id]
    # first we'll copy our test case input and output files to the docker container
    # for this first we create a folder called testcases in the container
    # then move on to two docker cp commands
    subprocess.call(["docker", "exec", container_id, "mkdir", "testcases"])
    subprocess.call(["docker", "cp", tc.input_file.name, "{}:/{}".format(container_id, input_filename)])
    subprocess.call(["docker", "cp", tc.output_file.name, "{}:/{}".format(container_id, output_filename)])

    # the timeout_lst list makes sure that the user code does not run over the time limit
    # it makes use of the standard unix timeout command

# Path: judge/models.py
# class Coder(models.Model):
#     user = models.OneToOneField(User)
#     link = models.URLField()
#     score = models.DecimalField(default = 0, decimal_places = 3, max_digits = 100)
#     rank = models.IntegerField(default = -1)
#     problems_tried = models.ForeignKey('Problem', null = True, related_name = "problems_tried")
#     problems_ac = models.ForeignKey('Problem', null = True, related_name = "problems_ac")
# 
#     def __unicode__(self):
#         return self.user.username
# 
# class Submission(models.Model):
#     STATUSES = (
#                 ("NT", "Not tested"),
#                 ("CE", "Compile Error"),
#                 ("TL", "Time Limit Exceeded"),
#                 ("RE", "Runtime Error"),
#                 ("AC", "Accepted")
#                 )
#     submitter = models.ForeignKey(Coder, null = True)
#     problem = models.ForeignKey(Problem, default = None, null = True)
#     status = models.CharField(max_length = 2, default = "NT", choices = STATUSES)
#     lang = models.CharField(max_length = 4, default = "C", choices = LANGUAGES)
#     code = models.TextField(default="")
#     created = models.DateTimeField(auto_now_add=True)
#     private = models.BooleanField(default = True)
# 
# class Problem(models.Model):
#     # Problem name (example: life, the universe and everything)
#     name = models.CharField(max_length=255)
#     # Problem code (example: TEST)
#     code = models.CharField(max_length=20, unique = True)
#     # Problem link (example: poj.com/problems/TEST)
#     link = models.URLField()
#     # Problem statement
#     statement = models.TextField()
# 
#     num_submissions = models.IntegerField(default = 0) # number of submissions
#     num_ac = models.IntegerField(default = 0)     # number of accepted submissions
#     num_wa = models.IntegerField(default = 0)          # number of wrong answers
#     num_re = models.IntegerField(default = 0)          # number of runtime errors
#     num_tle = models.IntegerField(default = 0)         # number of tles
#     num_ce = models.IntegerField(default = 0)
#     date_added = models.DateTimeField(auto_now_add = True) # When added
#     time_limit = models.IntegerField(default=1)         # Time Limit
#     source = models.CharField(max_length=255)
#     num_tests = models.IntegerField(default = 1)
# 
#     author = models.ForeignKey('Coder', null = True)
# 
#     def __unicode__(self):
#         return self.code
# 
# class TestCase(models.Model):
#     problem = models.ForeignKey(Problem)
#     input_file = models.FileField(upload_to=in_upload_path)
#     output_file = models.FileField(upload_to=out_upload_path)
# 
#     def __unicode__(self):
#         return self.problem.code


# Path: judge/tasks.py
from celery.decorators import task
from judge.models import Coder, Submission, Problem, TestCase
import subprocess
import os

    cur_problem = submission.problem
    cur_problem.num_submissions += 1
    tc = TestCase.objects.get(problem = cur_problem)
    ## this is real spaghetti code written in 2 hours
    # input_filename and output_filename only contain the file names such as 1.in, 2.out etc
    # tc.input_file.name on the other hand contains testcases/ (example: testcases/1.in)
    input_filename = tc.input_file.name.split("/")[1]
    output_filename = tc.output_file.name.split("/")[1]
    print("input = {}, output = {}".format(input_filename, output_filename))


    # first create a new docker container of the image poj with memory limit 256M so
    # user code does not kill the server
    container_id = subprocess.check_output(["docker", "run", "-it", "-m","256M","-d", "poj"])
    # decode bytestring to utf-8 and remove the last newline from docker output
    container_id = container_id.decode('utf-8')
    print(container_id)
    container_id = container_id[:len(container_id)-1]

    # this list can be appended to any command to make it run in container_id
    docker_lst  = ["docker", "exec", container_id]
    # first we'll copy our test case input and output files to the docker container
    # for this first we create a folder called testcases in the container
    # then move on to two docker cp commands
    subprocess.call(["docker", "exec", container_id, "mkdir", "testcases"])
    subprocess.call(["docker", "cp", tc.input_file.name, "{}:/{}".format(container_id, input_filename)])
    subprocess.call(["docker", "cp", tc.output_file.name, "{}:/{}".format(container_id, output_filename)])

    # the timeout_lst list makes sure that the user code does not run over the time limit
    # it makes use of the standard unix timeout command

    tl = cur_problem.time_limit