#!/usr/bin/env python3

import re
from gradelib import *

r = Runner(save("xv6.out"))

PTE_PRINT = """page table 0x0000000087f6b000
 ..0: pte 0x0000000021fd9c01 pa 0x0000000087f67000
 .. ..0: pte 0x0000000021fd9801 pa 0x0000000087f66000
 .. .. ..0: pte 0x0000000021fda01b pa 0x0000000087f68000
 .. .. ..1: pte 0x0000000021fd9417 pa 0x0000000087f65000
 .. .. ..2: pte 0x0000000021fd9007 pa 0x0000000087f64000
 .. .. ..3: pte 0x0000000021fd8c17 pa 0x0000000087f63000
 ..255: pte 0x0000000021fda801 pa 0x0000000087f6a000
 .. ..511: pte 0x0000000021fda401 pa 0x0000000087f69000
 .. .. ..509: pte 0x0000000021fdcc13 pa 0x0000000087f73000
 .. .. ..510: pte 0x0000000021fdd007 pa 0x0000000087f74000
 .. .. ..511: pte 0x0000000020001c0b pa 0x0000000080007000"""

VAL_RE = "(0x00000000[0-9a-f]+)"
INDENT_RE = r"\s*\.\.\s*"
INDENT_ESC = "\\\s*\.\.\\\s*"

@test(0, "pgtbltest")
def test_pgtbltest():
    r.run_qemu(shell_script([
        'pgtbltest'
    ]), timeout=300)

@test(10, "pgtbltest: ugetpid", parent=test_pgtbltest)
def test_nettest_():
    r.match('^ugetpid_test: OK$')

@test(10, "pgtbltest: pgaccess", parent=test_pgtbltest)
def test_nettest_():
    r.match('^pgaccess_test: OK$')

@test(10, "pte printout")
def test_pteprint():
    first = True
    r.run_qemu(shell_script([
        'echo hi'
    ]))
    r.match('^hi')
    p = re.compile(VAL_RE)
    d = re.compile(INDENT_RE)
    for l in PTE_PRINT.splitlines():
        l = d.sub(INDENT_ESC, l)
        l = p.sub(VAL_RE, l)
        r.match(r'^{}$'.format(l))
        if first:
            first = False
        else:
            matches = re.findall(r'^{}$'.format(l), r.qemu.output, re.MULTILINE)
            assert_equal(len(matches[0]), 2)
            pa = (int(matches[0][0], 16) >> 10) << 12
            assert_equal(int(matches[0][1], 16), pa)

@test(5, "answers-pgtbl.txt")
def test_answers():
    # just a simple sanity check, will be graded manually
    check_answers("answers-pgtbl.txt")

@test(0, "usertests")
def test_usertests():
    r.run_qemu(shell_script([
        'usertests -q'
    ]), timeout=300)

@test(10, "usertests: all tests", parent=test_usertests)
def test_usertests():
    r.match('^ALL TESTS PASSED$')

@test(1, "time")
def test_time():
    check_time()

run_tests()