#!/usr/bin/env python

import os
import sys
import shutil

## Requirements to use this program.
## The files that are to be marked must be named with the for <asstname>q<questionnumber>.{ss,py}
## For example,  a9q4.ss , testq1.py
## The languages that this is set up for are Scheme and Python

# sets the course number to be used
crs = 116

# Save this file to your home directory (in the course account)
# to call this program, ~/make-all.py x n
# x is the name of the assignment (e.g a4), and
# n is the number of questions in the assignment
if len(sys.argv)!= 3:
    print "Usage:", sys.argv[0], "<assignment number> <number of questions>"
    sys.exit(1)

asstnum = sys.argv[1] #Assignment name
number_of_qs = sys.argv[2] #Number of files to be submitted

# allows the user to choose the language for the assignment, and sets the file extension as required
language = raw_input('What language? ')
while not (language in ['beginner', 'intermediate',
                     'intermediate-lambda', 'advanced', 'python']):
    print 'Valid languages are: \n beginner, intermediate, intermediate-lambda advanced or python\n'    
    language = raw_input('What language? ')
if language == 'python':
    suffix ='py'
else:
    suffix = 'ss'
###########################


# makes the handin folder with .subfiles
# This file says what files are to be submitted.
# Note that the filenames must be of the form described above
# e.g.
# a2q1.ss
# a2q2.ss
# a2q3.ss
# a2q4.ss
if not os.path.exists('/u4/cs%d/handin/%s' %(crs,asstnum)):
    os.makedirs('/u4/cs%d/handin/%s' %(crs,asstnum))
os.chmod('/u4/cs%d/handin/%s' %(crs,asstnum), 0755)
os.chdir('/u4/cs%d/handin/%s' %(crs,asstnum))
# Note that creation of .subfiles will make the assignment visible
# to students on Odessey, however the assignment will not be opened
# for submission
subfile = file (".subfiles","w")
for i in range(int(number_of_qs)):
    subfile.write("%sq%s.%s\n" %(asstnum,i+1,suffix))
subfile.close()
###########################

# creates the important folders and files within marking:
# a?, test.1, runTests, computeMarks, in, provided, answers
# Always creates the testing suite test.1
if not os.path.exists('/u4/cs%d/marking/%s' %(crs,asstnum)):
    os.makedirs('/u4/cs%d/marking/%s' %(crs,asstnum))
os.chmod('/u4/cs%d/marking/%s' %(crs,asstnum), 0710)
os.chdir('/u4/cs%d/marking/%s' %(crs,asstnum))

##test.1
if not os.path.exists('/u4/cs%d/marking/%s/test.1' %(crs,asstnum)):
    os.makedirs('/u4/cs%d/marking/%s/test.1' %(crs,asstnum))
os.chmod('/u4/cs%d/marking/%s/test.1' %(crs,asstnum), 0750)
os.chdir('/u4/cs%d/marking/%s/test.1' %(crs,asstnum))

##runTests
shutil.copy('/u4/cs%d/marking/Useful Modules/runTests'%(crs),
            '/u4/cs%d/marking/%s/test.1' %(crs,asstnum))
os.chmod('/u4/cs%d/marking/%s/test.1/runTests' %(crs,asstnum), 0750)

##computeMarks
shutil.copy('/u4/cs%d/marking/Useful Modules/computeMarks_auto' %(crs),
            '/u4/cs%d/marking/%s/test.1/computeMarks' %(crs,asstnum))
os.chmod('/u4/cs%d/marking/%s/test.1/runTests' %(crs,asstnum), 0750)

##in
if not os.path.exists('/u4/cs%d/marking/%s/test.1/in' %(crs,asstnum)):
    os.makedirs('/u4/cs%d/marking/%s/test.1/in' %(crs,asstnum))
os.chmod('/u4/cs%d/marking/%s/test.1/in' %(crs,asstnum), 0750)

##provided
if not os.path.exists('/u4/cs%d/marking/%s/test.1/provided' %(crs,asstnum)):
    os.makedirs('/u4/cs%d/marking/%s/test.1/provided' %(crs,asstnum))
os.chmod('/u4/cs%d/marking/%s/test.1/provided' %(crs,asstnum), 0750)

##answers
if not os.path.exists('/u4/cs%d/marking/%s/test.1/answers' %(crs,asstnum)):
    os.makedirs('/u4/cs%d/marking/%s/test.1/answers' %(crs,asstnum))
os.chmod('/u4/cs%d/marking/%s/test.1/answers' %(crs,asstnum), 0500)
###########################

# For language python, puts suppress_prompt.py in provided
# This ignores anything that has been put in the prompt for raw_input(),
# meaning that students can put
if language == 'python':
    fppyth = file('/u4/cs%d/marking/Useful Modules/suppress_prompt.py' %(crs),'r')
    lines = fppyth.readlines()
    fppyth.close()
    os.chdir('/u4/cs%d/marking/%s/test.1/provided/' %(crs,asstnum))
    output = file('suppress_prompt.py','w')
    output.writelines(lines)
    output.close()
    os.chmod('/u4/cs%d/marking/%s/test.1/provided/suppress_prompt.py' %(crs,asstnum), 0750)
###########################

# For language python, creates the 'solution' folder
if language == 'python':
    os.chdir('/u4/cs%d/marking/%s/test.1/' %(crs,asstnum))
    os.mkdir('/u4/cs%d/marking/%s/solution' %(crs,asstnum))
    os.chmod('/u4/cs%d/marking/%s/solution' %(crs,asstnum), 0700)
###########################
    
# Puts fpequal.ss in the provided folder, if needed
modules = raw_input("Do you need a 'check-within' equalilty function (y/n)? ")
which_qs = range(int(number_of_qs))
if modules == 'y':
    fpeq = file('/u4/cs%d/marking/Useful Modules/fpequal.ss' %(crs),'r')
    lines = fpeq.readlines()
    fpeq.close()
    os.chdir('/u4/cs%d/marking/%s/test.1/provided/' %(crs,asstnum))
    output = file('fpequal.ss','w')
    output.writelines(lines)
    output.close()
###########################

# determines which which questions need an alternate equality
    os.chmod('/u4/cs%d/marking/%s/test.1/provided/fpequal.ss' %(crs,asstnum), 0750)
    print '\nThe equalilty functions are check-close and check-close-list.'
    
    print "Which equality function for (type nothing for q's with normal equality):"
    for i in range(int(number_of_qs)):
        eq_fun = raw_input( 'question %d? ' %(i+1))
        while not (eq_fun in ['','check-close','check-close-list']):
            eq_fun = raw_input('Not a valid input. Try again: ')
        if eq_fun in ['check-close', 'check-close-list']:
            which_qs[i] = eq_fun
###########################

# For language advanced, puts checkvoid.ss in provided
if language == 'advanced':
    voider = file('/u4/cs%d/marking/Useful Modules/checkvoid.ss' %(crs),'r')
    lines = voider.readlines()
    voider.close()
    os.chdir('/u4/cs%d/marking/%s/test.1/provided/' %(crs,asstnum))
    output = file('checkvoid.ss','w')
    output.writelines(lines)
    output.close()
    os.chmod('/u4/cs%d/marking/%s/test.1/provided/checkvoid.ss' %(crs,asstnum), 0750)
###########################

# Creates the main options.ss file
os.chdir('/u4/cs%d/marking/%s/test.1/in/' %(crs,asstnum))
main_options = file ("options.ss","w")
main_options.write('(desc "Assignment %s")\n' %(asstnum))

if language == 'python':
    main_options.write('(language %s)\n' %(language))
    main_options.write('(modules "suppress_prompt")\n')
elif language == 'advanced':
    main_options.write('(language scheme/%s)\n' %(language))
    main_options.write('(modules checkvoid.ss)\n')
else:
    main_options.write('(language scheme/%s)\n' %(language))
main_options.write('(value 1)')
main_options.close()
os.chmod('/u4/cs%d/marking/%s/test.1/in/options.ss' %(crs,asstnum),0750)
###########################

# Creates mark-scheme file
def make_mark_scheme(asstnum, numofqs):
    ms_file = file('/u4/cs%d/marking/%s/test.1/mark-scheme'%(crs,asstnum),'w')
    ms_file.write('".ad c\n\
.br\n\
    ========================================================================\n\
.br\n\
XXXXX  XXXXX  X     X  XXXX   X      XXXXX  XXXXX  XXXXX    \n\
  X    X      XXX XXX  X  XX  X      X   X    X    X        \n\
  X    XXX    X XXX X  X  XX  X      XXXXX    X    XXX      \n\
  X    X      X  X  X  XXXX   X      X   X    X    X        \n\
  X    X      X     X  X      X      X   X    X    X        \n\
  X    XXXXX  X     X  X      XXXXX  X   X    X    XXXXX    \n\
<----Term---> CS %d Assignment %s\n\
\n\
.br\n\
\n\
Marked By:                           TOTAL:           / %d\n\
.br\n\
========================================================================\n\
.br\n\
.ad l\n\
.in 13\n\n\
'%(crs,asstnum[1],(20 * int(numofqs))))

    for i in range(int(numofqs)):
        if language == 'python' or language == 'advanced':
            eff = '/Effects'
        else:
            eff = ''
        ms_file.write('.ti -13\n\
________/20 Problem %s: xxxxxxxxxxxx\n\
\n\
.ti -9\n\
________/x Design recipe\n\
\n\
.ti -5\n\
________/x  Contract\n\
\n\
.ti -5\n\
________/x  Purpose%s\n\
\n\
.ti -5\n\
________/x  Examples\n\
\n\
.ti -5\n\
________/x  Tests\n\
\n\
.ti -9\n\
________/x  Style\n\
\n\
.ti -9\n\
$t%se/$t%so Autotesting\n\
\n' %(i+1,eff,i+1,i+1))
    ms_file.write('"')
    ms_file.close()

make_mark_scheme(asstnum,number_of_qs)
###########################

# creates options.ss given an assignment number
# and a question number
def write_options(asstnum, qnum):
    if not os.path.exists('/u4/cs%d/marking/%s/test.1/in/%s' %(crs,asstnum, qnum)):
        os.makedirs('/u4/cs%d/marking/%s/test.1/in/%s' %(crs,asstnum, qnum))
    os.chmod('/u4/cs%d/marking/%s/test.1/in/%s' %(crs,asstnum, qnum),0750)    
    os.chdir('/u4/cs%d/marking/%s/test.1/in/%s' %(crs,asstnum, qnum))
    output = file("options.ss","w")
    if isinstance(which_qs[int(qnum-1)],str):
        output.write('(modules fpequal.ss)\n')
        output.write('(equal %s)\n' %(which_qs[int(qnum) - 1]))
    output.write('(desc "Tests for Question %s")\n' %(qnum))
    output.write('(loadcode "%sq%s.%s")\n' %(asstnum, qnum, suffix))
    output.close()
    os.chmod('/u4/cs%d/marking/%s/test.1/in/%s/options.ss' %(crs,asstnum, qnum),0750)
    return None
###########################

# creates the options.ss file for each of the questions
counter = 1
while counter <= int(number_of_qs):
    write_options(asstnum, counter)
    print("Created options.ss for question %s" %counter)
    counter += 1
###########################

# copies the all the files to a public test folder
if os.path.exists('/u4/cs%d/marking/%s/test.pt' %(crs,asstnum)):
    shutil.rmtree('/u4/cs%d/marking/%s/test.pt' %(crs,asstnum))
shutil.copytree('/u4/cs%d/marking/%s/test.1'%(crs,asstnum),'/u4/cs%d/marking/%s/test.pt'%(crs,asstnum))
shutil.copy('/u4/cs%d/marking/Useful Modules/computeMarks_pub' %(crs),
            '/u4/cs%d/marking/%s/test.pt/computeMarks' %(crs,asstnum))
###########################

# creates the mark-scheme file for use in the public testing
pub_mark_scheme = file('/u4/cs%d/marking/%s/test.pt/mark-scheme' %(crs,asstnum), 'w')
pub_mark_scheme.write('Assignment %s Public Testing\n\n' %(asstnum))
pub_mark_scheme.write('These tests are provided to check to see if your functions perform correctly on simple cases. There will be no guarantee that your answers will be 100% correct. Hence, remember to create more tests to ensure that your answers are correct.')
pub_mark_scheme.close()
###########################