#!/usr/bin/python3
# Create HTML files with Selection evaluation results for each participant
#    in current directory. Creates evaluation.html and reviews/
#
# cd Selection
# usage: python3 ../create-evaluation-files.py \
#    ../registrations.csv ../reviews.csv [../assign-*.csv]
#
# Some --- columns needs to be renamed in evaluation-results.csv
# First column --- to -o-
# Column --- for each preference stating Does not meet requirements needs to be renamed to -n-
#
import sys
import csv
import os
import re
import string
from posix import unlink
from datetime import datetime
from collections import Counter
import glob


# enter SoHPC year
SoHPC_year = "2022" 

#
# Basic skeleton of html file (header, footer and content in the middle (parameter 3)
# Also include place holders for file title (0) and date (1)
skeleton = """
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta http-equiv="CACHE-CONTROL" content="NO-CACHE">
    <meta http-equiv="EXPIRES" content="0">
    <title>{{TITLE}}</title>
    <script type="text/javascript">
        function goto_project(){
            var myselect = document.getElementById("project_id_list");
            window.location.href = '#project_'+myselect.options[myselect.selectedIndex].value;
        }
    </script>
<style>
  body {background-color:white}
  .size {
  background-color: white;
  margin:0 auto;
  font-family: arial;
  font-size: 12px;
  }
  div.title { font-size: 16px; font-weight: bold;}
  div {margin-bottom: 2px;}
  table.list {
      width: 100%;
      padding: 0px;
      margin: 0px;
      -webkit-border-vertical-spacing: 0px;
  }
  table.list tr:nth-child(even) {
    background-color: #EFEFEF;
  }
  table.list tr.head, table.list tr.foot {
      background-color: #BBBBBB;
  }
      table.list tr.head th {
          border-bottom: 1px solid #aaaaaa;
      }
      table.list tr.foot th {
          border-top: 1px solid #aaaaaa;
      }

  table.list tr td.id {
      text-align: right;
      padding-right: 5px;
      border-left: 0px;
  }
  table.list tr:hover {
    background-color: LightGreen;
  }
  td.dataCaptionTD {
      width: 150px;
  }
  td.dataSubCaptionTD {
      width: 150px;
  }
  th.overall_comment, td.overall_comment {
      width: 15%;
      vertical-align: top;
  }
  table.list tr table.no_bg_coloring tr {
      background-color: transparent;
  }
  table.list tr.registrant_selected {
      background-color: #ADBDE3;
      font-weight: bold;
  }
  table.list tr.registrant_selected_tentative {
      background-color: #ee9999;
      font-weight: bold;
  }
  table.list tr.registrant_selected_other {
      text-decoration: line-through;
      background-color: #00EFEF;
      font-style: italic;
      color: #999999;
  }
  table.list tr.registrant_selected_other a {
      color: #999999;
  }
  table.list tr.registrant_withdrawn {
      text-decoration: line-through;
      font-style: italic;
      color: #999999;
  }
  table.list tr.registrant_withdrawn a {
      color: #999999;
  }
</style>
</head>
<body>
<div class=size>
<br>
<br>
<div style="font-size: 16px; text-align: center; font-weight: bold;">Summer of HPC project evaluation results</div>
<br><br>
<div ><span style="float:right;"><b>Date</b>: {{DATE}}</span></div> 
{{CONTENT}}
</body>
</html>
"""

#
# Main content of index.html file. It holds list of projects and particiants (sorted by score)
#
index_data = """
<br>
<a name="projects"></a>
Content: [<a href="#projects">Project list</a>]&nbsp;&nbsp;[<a href="#registrants">Registrant list</a>]
<br>
<br>
<h2>PROJECT LIST WITH REGISTRANTS</h2>

<table>
<tr valign="top">
    <td>
        Projects and selected registrants (students):
        <table class="list" style="width: auto;">
        <tr class="head">
            <td>Project: ID - name</td>
            <td>Selected registrant (link to application)</td>
            <td>Country</td>
            <td>Gender</td>
            <td>Age</td>
            <td>E-mail</td>
            <td colspan="2">Evaluation<br>details</td>
        </tr>
        {{PROJECT_LIST_AND_SELECTED_PARTICIPANTS}}
        </table>
    </td>
    <td width="10%">&nbsp;</td>
    <td>
        Countries - all and selected.
        <table class="list">
        <tr class="head">
            <th>&nbsp;</th>
            <th colspan="3">Registrants</th>
        </tr>
        <tr class="head">
            <th>Country</th>
            <th width="60px">All</th>
            <th width="60px">Selected</th>
            <th width="60px">[%]</th>
        </tr>
        {{COUNTRY_PARTICIPANTS_LIST}}
        </table>
    </td>
</tr>
</table>
<hr>
{{CONTENT_PROJECTS}}

<br>
<br>
<br>
<hr>
<br>
<a name="registrants"></a>
Content: [<a href="#projects">Project list</a>]&nbsp;&nbsp;[<a href="#registrants">Registrant list</a>]
<br>
<br>
<h2>REGISTRANTS EVALUATIONS</h2>
{{CONTENT_REGISTRANTS}}
"""

# layout of project in TOC
project_selected_participant_row = """
    <tr>
        <td rowspan="{{PROJECT_ROW_SPAN}}"><a href="#project_{{PROJECT_ID}}">{{PROJECT_ID}} - {{PROJECT_NAME}}</td>
        <td>{{PARTICIPANTS_LIST}}</td>
    </tr>
"""

# layout of list of participants; value is added to "skeleton"
project_html_data = """
<br>
<a name="project_{{PROJECT_ID}}"></a>
<h3>{{PROJECT_ID}} - {{PROJECT_NAME}}</h3>
On mouseover (put mouse cursor above mark) and additional explanation will be displayed. <div style="float: right;"><a href="#projects">[to top]</a></div>
<table class="list">
<head>
    <tr class="head">
        <th>&nbsp;</th>
        <th>&nbsp;</th>
        <th>&nbsp;</th>
        <th>&nbsp;</th>
        <th>&nbsp;</th>
        <th>&nbsp;</th>
        <th colspan="2">Comment</th>
        <th colspan="2">Pref.1</th>
        <th colspan="2">Pref.2</th>
        <th colspan="2">Pref.3</th>
        <th colspan="3">Motivation</th>
        <th colspan="3">Ambasador</th>
        <th colspan="3">Technical</th>
        <th>&nbsp;</th>
    </tr>
    <tr class="head">
        <th>No.</th>
        <th>Name (ID)</th>
        <th>Country</th>
        <th>Gender</th>
        <th>Age</th>
        <th>Choice</th>
        <th class="overall_comment">P1</th>
        <th class="overall_comment">P2</th>
        <th title="[X] = Student meet compulsory preferences.\n[  ] = Student DOES NOT meet compulsory preferences.">(?)</th>
        <th title="[X] = Student meet desirable prerequisites.\n[  ] = Student DOES NOT meet desirable preferences.">(?)</th>
        <th title="[X] = Student meet compulsory preferences.\n[  ] = Student DOES NOT meet compulsory preferences.">(?)</th>
        <th title="[X] = Student meet desirable prerequisites.\n[  ] = Student DOES NOT meet desirable preferences.">(?)</th>
        <th title="[X] = Student meet compulsory preferences.\n[  ] = Student DOES NOT meet compulsory preferences.">(?)</th>
        <th title="[X] = Student meet desirable prerequisites.\n[  ] = Student DOES NOT meet desirable preferences.">(?)</th>
        <th>P1</th>
        <th>P2</th>
        <th>Avg</th>
        <th>P1</th>
        <th>P2</th>
        <th>Avg</th>
        <th>P1</th>
        <th>P2</th>
        <th>Avg</th>
        <th>Average</th>
    </tr>
</thead>
<tbody>
{{REGISTRANT_DATA}}
</tbody>
</table>
"""

# row for 
project_user_row = """
<tr class="{{REGISTRANT_SELECTED}}">
    <td class="id">{{I}}</td>
    <td><a href="{{HTML_FILENAME}}">{{NAME}} ({{ID}})</a> <a href='{{EVALUATION_HTML_LINK_1}}'>[eval1]</a> <a href='{{EVALUATION_HTML_LINK_2}}'>[eval2]</a></td>
    <td>{{COUNTRY}}</td>
    <td align="center">{{GENDER}}</td>
    <td align="center">{{AGE}}</td>
    <td class="{{CHOICE}}" align="center">{{CHOICE}}</td>
    <td align="left" class="overall_comment"><i>{{REVIEWER_1}}:</i><br>{{OVERALL_COMMENT_1}}</td>
    <td align="left" class="overall_comment"><i>{{REVIEWER_2}}:</i><br>{{OVERALL_COMMENT_2}}</td>
    <td align="center" title="{{PREFERENCE_1_COMPULSORY}}">{{PREFERENCE_1_SHORT_COMPULSORY}}</td>
    <td align="center" title="{{PREFERENCE_1_DESIRABLE}}">{{PREFERENCE_1_SHORT_DESIRABLE}}</td>
    <td align="center" title="{{PREFERENCE_2_COMPULSORY}}">{{PREFERENCE_2_SHORT_COMPULSORY}}</td>
    <td align="center" title="{{PREFERENCE_2_DESIRABLE}}">{{PREFERENCE_2_SHORT_DESIRABLE}}</td>
    <td align="center" title="{{PREFERENCE_3_COMPULSORY}}">{{PREFERENCE_3_SHORT_COMPULSORY}}</td>
    <td align="center" title="{{PREFERENCE_3_DESIRABLE}}">{{PREFERENCE_3_SHORT_DESIRABLE}}</td>
    <td align="center" title="{{REVIEWER_1}}: {{MOTIVATION_COMMENT_P1}}">{{MOTIVATION_P1}}</td>
    <td align="center" title="{{REVIEWER_2}}: {{MOTIVATION_COMMENT_P2}}">{{MOTIVATION_P2}}</td>
    <td align="center">{{MOTIVATION_AVG}}</td>
    <td align="center" title="{{REVIEWER_1}}: {{AMBASADOR_COMMENT_P1}}">{{AMBASADOR_P1}}</td>
    <td align="center" title="{{REVIEWER_2}}: {{AMBASADOR_COMMENT_P2}}">{{AMBASADOR_P2}}</td>
    <td align="center">{{AMBASADOR_AVG}}</td>
    <td align="center" title="{{REVIEWER_1}}: {{TECHNICAL_COMMENT_P1}}">{{TECHNICAL_P1}}</td>
    <td align="center" title="{{REVIEWER_2}}: {{TECHNICAL_COMMENT_P2}}">{{TECHNICAL_P2}}</td>
    <td align="center">{{TECHNICAL_AVG}}</td>
    <td align="center">{{AVERAGE_P}}</td>
</tr>
"""

# layout of single row for each participant; content is added to "person_data"
registrant_list = """
On mouseover (put mouse cursor above mark) and additional explanation will be displayed. 
<table class="list">
<tr class="head">
    <th>&nbsp;</th>
    <th>&nbsp;</th>
    <th colspan="2">Comment</th>
    <th colspan="2">Pref.1</th>
    <th colspan="2">Pref.2</th>
    <th colspan="2">Pref.3</th>
    <th colspan="3">Motivation</th>
    <th colspan="3">Ambasador</th>
    <th colspan="3">Technical</th>
    <th>&nbsp;</th>
</tr>
<tr class="head">
    <th>No.</th>
    <th>Registrant</th>
    <th class="overall_comment">P1</th>
    <th class="overall_comment">P2</th>
    <th title="[X] = Student meet compulsory preferences.\n[  ] = Student DOES NOT meet compulsory preferences.">(?)</th>
    <th title="[X] = Student meet desirable prerequisites.\n[  ] = Student DOES NOT meet desirable preferences.">(?)</th>
    <th title="[X] = Student meet compulsory preferences.\n[  ] = Student DOES NOT meet compulsory preferences.">(?)</th>
    <th title="[X] = Student meet desirable prerequisites.\n[  ] = Student DOES NOT meet desirable preferences.">(?)</th>
    <th title="[X] = Student meet compulsory preferences.\n[  ] = Student DOES NOT meet compulsory preferences.">(?)</th>
    <th title="[X] = Student meet desirable prerequisites.\n[  ] = Student DOES NOT meet desirable preferences.">(?)</th>
    <th>P1</th>
    <th>P2</th>
    <th>Avg</th>
    <th>P1</th>
    <th>P2</th>
    <th>Avg</th>
    <th>P1</th>
    <th>P2</th>
    <th>Avg</th>
    <th>Average</th>
</tr>
{0}
<tr class="foot">
    <th>No</th>
    <th>Registrant</th>
    <th colspan="2">Comment</th>
    <th colspan="2">Pref.1</th>
    <th colspan="2">Pref.2</th>
    <th colspan="2">Pref.3</th>
    <th colspan="3">Motivation</th>
    <th colspan="3">Ambasador</th>
    <th colspan="3">Technical</th>
    <th>Average</th>
</tr>
</table>
"""

# layout of registrant daata + scores of evaluation + average scores
person_row = """
<tr class="{{REGISTRANT_SELECTED}}">
    <td class="id">{{I}}</td>
    <td><a href="{{HTML_FILENAME}}">{{REGISTRANT_NAME}}; {{COUNTRY}}, {{GENDER}}, {{AGE}} years (ID: {{REGISTRANT_ID}})</a><br>Preferred projects: {{PROJECT_ID_LIST}}</td>
    <td align="left" class="overall_comment"><i>{{REVIEWER_1}}:</i><br>{{OVERALL_COMMENT_1}}</td>
    <td align="left" class="overall_comment"><i>{{REVIEWER_2}}:</i><br>{{OVERALL_COMMENT_2}}</td>
    <td align="center" title="{{PREFERENCE_1_COMPULSORY}}">{{PREFERENCE_1_SHORT_COMPULSORY}}</td>
    <td align="center" title="{{PREFERENCE_1_DESIRABLE}}">{{PREFERENCE_1_SHORT_DESIRABLE}}</td>
    <td align="center" title="{{PREFERENCE_2_COMPULSORY}}">{{PREFERENCE_2_SHORT_COMPULSORY}}</td>
    <td align="center" title="{{PREFERENCE_2_DESIRABLE}}">{{PREFERENCE_2_SHORT_DESIRABLE}}</td>
    <td align="center" title="{{PREFERENCE_3_COMPULSORY}}">{{PREFERENCE_3_SHORT_COMPULSORY}}</td>
    <td align="center" title="{{PREFERENCE_3_DESIRABLE}}">{{PREFERENCE_3_SHORT_DESIRABLE}}</td>
    <td align="center" title="{{REVIEWER_1}}: {{MOTIVATION_COMMENT_P1}}">{{MOTIVATION_P1}}</td>
    <td align="center" title="{{REVIEWER_2}}: {{MOTIVATION_COMMENT_P2}}">{{MOTIVATION_P2}}</td>
    <td align="center">{{MOTIVATION_AVG}}</td>
    <td align="center" title="{{REVIEWER_1}}: {{AMBASADOR_COMMENT_P1}}">{{AMBASADOR_P1}}</td>
    <td align="center" title="{{REVIEWER_2}}: {{AMBASADOR_COMMENT_P2}}">{{AMBASADOR_P2}}</td>
    <td align="center">{{AMBASADOR_AVG}}</td>
    <td align="center" title="{{REVIEWER_1}}: {{TECHNICAL_COMMENT_P1}}">{{TECHNICAL_P1}}</td>
    <td align="center" title="{{REVIEWER_2}}: {{TECHNICAL_COMMENT_P2}}">{{TECHNICAL_P2}}</td>
    <td align="center">{{TECHNICAL_AVG}}</td>
    <td align="center">{{AVERAGE_P}}</td>
</tr>
"""

#
# Save given title/date/content into given file
#
def save_content(filename, skeleton, title, date, content):
    skeleton = skeleton.replace("{{TITLE}}", title)
    skeleton = skeleton.replace("{{DATE}}",  date)
    skeleton = skeleton.replace("{{CONTENT}}", content)
    # open file and write content
    f = open(filename, "w")
    f.write(skeleton)
    f.close()

    return


#
# Read file and return header and data rows
#
def read_csv_file(filename):
    # Open the CSV file for reading -- evaluation data
    reader = csv.reader(open(filename))
    header_org = next(reader)
    header = []
    # correct names of fields (columns); remove all non-printable chars and "
    include = set(string.printable)
    
    for key in header_org:
        # check all header names/columns
        name = "".join(ch for ch in key if ch in include)
        name = name.replace('"', "")
        header.append(name)
    
    #print(header)
    # get header len = number of fields/columns
    header_len = len(header)
    
    data_rows = []
    # Read a single row from the CSV file
    for row in reader:
        if len(row) == 0:
            continue
        if row[0].startswith('#'):
            continue
        if len(row) != header_len:
            print("BAD DATA ROW ", ", ".join(row))
            continue
        data_rows.append(row)

    return { "header": header, "rows": data_rows } 

#
# Return number of points (score) for given evaluation part
# 0 if not defined. Values are written as %d Points.
#
def get_points_from_evaluation(value):
    point = 0
    
    if value:
        # check 
        #print(value)
        tmp_point = value.split(" ")[0].strip()
        
        if tmp_point:
            point = int(tmp_point)
    
    return point


#===========================================================
#== MAIN 
#===========================================================

# read both files
tmp_user_data = read_csv_file(sys.argv[1])
eval_data = read_csv_file(sys.argv[2])

#
# create user_data dictionary with id as key and other data as dictionay 
# for each row, keys are field names 
user_data = {}

for row in tmp_user_data['rows']:
    # process all rows
    dic=dict(zip(tmp_user_data['header'], row))
    #[print(key) for key in dic.keys()]
    if dic['ID'] == '':
        dic['ID'] = 0
    
    id = int(dic['ID'])
    link = glob.glob('../Application_Form/*_%d' % id)
    if len(link) == 0:
        print('Missing Application form for id %d' % id)
    link = link[0]
    dic.update({'link_application': "%s/index.html" % link})
    user_data.update({id:dic})

# load assignments
for a in sys.argv[3:]:
    for row in read_csv_file(a)['rows']:
        id = int(row[0])
        tentative = False
        if id < 0:
            id = -id
            tentative = True
        proj = row[1].strip()
        if user_data[id]['selected'] == proj:
            pass
        else:
            if user_data[id]['selected']:
                print("trying to reselect student %d from '%s' to '%s'\n" % (id, user_data[id]['selected'], proj))
            else:
                user_data[id]['selected'] = proj
                user_data[id]['tentative'] = tentative

#print(user_data)

if not os.path.exists("reviews"):
    # if does not exist, create cubdir for storing HTML files
    os.makedirs("reviews")
    
#get_file("cookies.txt", "54-0.pdf", "https://events.prace-ri.eu/event/367/manage/registration/users/54/attachments/0.pdf")
print("Creating HTML files: ")

# read registrant content template
f = open("../evaluation-detail-format.html", "r")
evaluation_content = f.read()
f.close()

n = datetime.now()
generation_date = "{0}. {1}. {2} @ {3}:{4}".format(n.day, n.month, n.year, n.hour, n.minute)

# data about projects and registrants sorted with project first, then all rgistrant data and scores...
project_data = {}
student_data = {}
country_data = {}

for id in user_data:
    # prepare array for student evaluation data
    student_data.update({id: {'motivation': {'p': ['', ''], 'comment': ['',''], 'avg': 0.}, 
                              'ambasador': {'p': ['', ''], 'comment': ['',''], 'avg': 0.}, 
                              'technical': {'p': ['', ''], 'comment': ['',''], 'avg': 0.}, 
                              'average': 0.,
                              'num_reviewers_done': 0,
                              'evaluation_detail_file': ['',''],
                              'reviewer': ['', ''], 
                              'overall_comment': ['', ''],
                              'preference': [[['',''], ['',''], ['','']], [['',''], ['',''], ['','']]]}
                         })

    if user_data[id]['selected'] in ['invalid', 'withdrawn', 'declined']:
        continue

    # store countries into separate array
    ctryName = user_data[id]['Country']
    
    if not ctryName in country_data:
        # add country to array
        country_data.update({ctryName : {'all': 0, 'selected': 0, 'percent': 0.0 }})
        
    # add another student
    country_data[ctryName]['all'] += 1

#print(student_data)
#print(eval_data)
for row in eval_data['rows']:
    # loop over all evaluations
    done_keys = {}
    dic=dict(zip(eval_data['header'], row))

#    print(dic)
    userID=int(dic["Applicant number"].replace("#",""))
    reviewerName=dic["Signature"].replace(" ","_")
    filename = "reviews/{0:03}_{1}.html".format(userID,reviewerName)

    #print("{0}: {1}".format(userID, user_data[userID]['Name']))
#    print(" - evaluation defined")

    # store points form evaluation
    sum = 0
    numReviewer = student_data[userID]['num_reviewers_done']
    
    if numReviewer < 2:
        student_data[userID]['evaluation_detail_file'][numReviewer] = filename
        student_data[userID]['reviewer'][numReviewer] = dic["Signature"]
        student_data[userID]['overall_comment'][numReviewer] = dic["Overall recommendation and comment"]
        
    else:
        print("{0}: {1}".format(userID, user_data[userID]['Name']))
        print("   -->> ERROR: too many reviewers!! -- {0}; only first 2 reviewers used.".format(numReviewer+1))
        continue
    
    # 2019 remapping
    remap = {
    'motivation': 'Motivation & Enthusiasm',
    'ambasador': 'Ambassador Potential',
    'technical': 'Technical ability'
    }
    for part in ['motivation', 'ambasador', 'technical']:
        # parse all fields, store the points and compute the average

        point = get_points_from_evaluation(dic[remap[part]])
        #print("    - {0}: {1} -> {2} (reviever num: {3})".format(part, dic[remap[part]], point, numReviewer))
        #print(dic[remap[part] + " comment"])

        if numReviewer < 2:
            student_data[userID][part]['p'][numReviewer] = point
            student_data[userID][part]['comment'][numReviewer] = dic[remap[part] + " comment"]
            
        if numReviewer == 0:
            # average is current values 
            student_data[userID][part]['avg'] = student_data[userID][part]['p'][0]
            sum += student_data[userID][part]['avg']
            
        else:
            # compute average from both marks
            student_data[userID][part]['avg'] = 0.5*(student_data[userID][part]['p'][0]+student_data[userID][part]['p'][1])
            sum += student_data[userID][part]['avg']

    # compute the average
    student_data[userID]['average'] = sum/3.
    student_data[userID]['num_reviewers_done'] += 1

 #   print("    - avg: {0:.2f}".format(student_data[userID]['average']);)
    #
    # generate registrant presentation HTML
    #
    content = evaluation_content
    # current preference
    currentPreference = ''

    for i in range(0,len(eval_data['header'])):
        # loop over header to preserve key order
        key = eval_data['header'][i]
        value = row[i].strip().replace("#","")
        #print(key, "|" + value + "|")
        # replace value for all keys in row
        html_fld = key.replace(" ", "_").upper()
        
        #print("key: {0}".format(html_fld))
        
        if html_fld in done_keys:
            # current key was already used in current row; add number at the end
            #print("found: {0}".format(html_fld))
            done_keys[html_fld] += 1
            html_fld = "{0}__{1}".format(html_fld, done_keys[html_fld])
        else:
            # key not used; add it to array for checking later
            done_keys.update({html_fld: 1})
        
#        print("key: " + key + ", html: " + html_fld + ", value=|" + value  + "|")
        #print(done_keys)

        content = content.replace("{{" + html_fld + "}}", value)
        
        if key == "Applicant number":
            # replace also add/replace participant full name and formated UID {0:03}
            userID = int(value)
            tmp_title = user_data[userID]['Name']
            formUID = value.strip().zfill(3)
            content = content.replace("{{REGISTRANT_NAME}}", tmp_title)
            content = content.replace("{{FORMATED_UID}}", formUID)
 
        elif key == "Submission Date":
            # 2019 format 
            # 2019-03-26 00:33:44.289498+00:00
            # display date + time in more nicer format
            #print(html_fld)
            if value != '':
                # n = datetime.strptime(value, '%y-%m-%d %H:%M:%S.%f+%z')
                # dateTime = "{0}. {1}. {2} @ {3}:{4}".format(n.day, n.month, n.year, n.hour, n.minute)
                content = content.replace("{{" + html_fld +"_DISP}}", value)
            else:
                content = content.replace("{{" + html_fld +"_DISP}}", "")

        elif key == 'Motivation & Enthusiasm':
            content = content.replace("{{%s}}" % "MOTIVATION", value)

        elif key == 'Motivation & Enthusiasm comment':
            content = content.replace("{{%s}}" % "MOTIVATION-COMMENT", value)

        elif key == 'Ambassador Potential':
            content = content.replace("{{%s}}" % "AMBASADOR", value)

        elif key == 'Ambassador Potential comment':
            content = content.replace("{{%s}}" % "AMBASADOR-COMMENT", value)

        elif key == 'Technical ability':
            content = content.replace("{{%s}}" % "TECHNICAL", value)

        elif key == 'Technical ability comment':
            content = content.replace("{{%s}}" % "TECHNICAL-COMMENT", value)

        elif key == 'Overall recommendation and comment':
            content = content.replace("{{%s}}" % "OVERALL", value)

        elif key.startswith("Project preference"):
            # process preference
            currentPreference = key[-1]
            #print('Current preference = ', currentPreference)
            currPrefIndex = int(currentPreference)-1
            # The string is in form:
            # Student meet compulsory preferences.; Student meet desirable prerequisites
            if 'meet compulsory' in value:
                student_data[userID]['preference'][numReviewer][currPrefIndex][0] = "[X]"
            else:
                student_data[userID]['preference'][numReviewer][currPrefIndex][0] = "[&nbsp;&nbsp;]"

            if 'meet desirable' in value:
                student_data[userID]['preference'][numReviewer][currPrefIndex][1] = "[X]"
            else:
                student_data[userID]['preference'][numReviewer][currPrefIndex][1] = "[&nbsp;&nbsp;]"

            if "not fit" in value:
                #student_data[userID]['preference'][numReviewer][currPrefIndex][2] = "[X]"
                content = content.replace("{{PREFERENCE_" + currentPreference +"_DOESNOTFIT}}", "[X]")
            else:
                # student_data[userID]['preference'][numReviewer][currPrefIndex][2] = "[&nbsp;&nbsp;]";
                content = content.replace("{{PREFERENCE_" + currentPreference +"_DOESNOTFIT}}", "[&nbsp;&nbsp;]")

            content = content.replace("{{PREFERENCE_" + currentPreference +"_COMPULSORY}}", student_data[userID]['preference'][numReviewer][currPrefIndex][0])
            content = content.replace("{{PREFERENCE_" + currentPreference +"_DESIRABLE}}", student_data[userID]['preference'][numReviewer][currPrefIndex][1])
            
    # add content into skeleton and write to file
    save_content(filename, skeleton, "Summer of HPC {0} - Registrant data".format(SoHPC_year), generation_date, content)

# for fldName in ['First Choice', 'Second Choice', 'Third Choice']:
#for fldName in ['1', '2', '3']:
#for fldName in ['Choice 1', 'Choice 2', 'Choice 3']:
#    choice = fldName.split(" ")[1].strip()
for fldName in ['1.', '2.', '3.']:
    choice = fldName[0:1]
    # get all three projects and first add all user's first choice, then second and then third choice
    for id in user_data:
        # loop over all users and extract projects and prepare arrays
        if user_data[id][fldName].strip():
            # project is defined
            proj = user_data[id][fldName].split(" ", 1)
            projID = int(proj[0].strip())
            projName = proj[1].strip()
        
            if not projID in project_data:
                # project does not exist; add an empty array for later addinf the data
                initData = {'name': projName, 'students': [], 'selected_student': {}}
                project_data.update({projID: initData})

            project_data[projID]['students'].append({'id': id, 'choice': choice})
        else:
            projID = 0
        user_data[id]['Choice'+choice+"ID"] = projID


for id in user_data:
    if user_data[id]['selected'].strip() in ['invalid', 'withdrawn', 'declined']:
        continue
    # loop over usr data and save selected students/registrants for each projct
    if user_data[id]['selected'].strip():
        # get project ID and order from selected number: 2001.1 (project ID.order of selection)
        _tmp = [el.strip() for el in user_data[id]['selected'].split(".")]
        projID = int(_tmp[0])
        projOrder = 0

        if len(_tmp) == 2:
            # get order from second part of 'selected' column
            if len(_tmp[1]) > 0:
                projOrder = int(_tmp[1])

        project_data[projID]['selected_student'][projOrder] = id
        # get student country and change country stat data
        ctryName = user_data[id]['Country']
        country_data[ctryName]['selected'] += 1
        
# now display project and student data into evaluation.html file
content_projects = ""
content_registrants = registrant_list

# sort projects by projectID
project_ids = sorted(project_data)

#
# layout project data + registrants for each project
#
proj_rows = ""
proj_select = ""

for projID in project_ids:
    # loop over all projects
    proj_row = project_html_data
    proj_row = proj_row.replace("{{PROJECT_NAME}}", project_data[projID]['name'])
    proj_row = proj_row.replace("{{PROJECT_ID}}", "{0}".format(projID))

    tmp_row = project_selected_participant_row.replace("{{PROJECT_ID}}", "{0}".format(projID))
    tmp_row = tmp_row.replace("{{PROJECT_NAME}}", project_data[projID]['name'])
    tmp_row = tmp_row.replace("{{PROJECT_ROW_SPAN}}", str(max(1, len(project_data[projID]['selected_student']))))

    if project_data[projID]['selected_student']:
        # add selected students in order defined in dict
        _cur_proj_students = ""
        _cur_proj_sep = ""

        for ordNum in sorted(project_data[projID]['selected_student'].keys()):
            # print students according to the order
            x = project_data[projID]['selected_student'][ordNum]
            _cur_proj_students += _cur_proj_sep+\
                "<a href='{0}'>{1}</a> ({7})</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{8}</td><td align='center'><a href='{5}'>[1]</a></td><td align='center'><a href='{6}'>[2]</a></td>"\
                .format(user_data[x]['link_application'], user_data[x]['Name'],
                        user_data[x]['Country'], user_data[x]['Gender'],
                        user_data[x]['Age (years)'],
                        student_data[x]['evaluation_detail_file'][0],
                        student_data[x]['evaluation_detail_file'][1],
                        user_data[x]['ID'],
                        user_data[x]['Email'])
            if user_data[x]['tentative']:
                _cur_proj_students += "<td>TENTATIVE</td>"
            if user_data[x]['I am confirming my participation for the selected project'] != "Yes":
                _cur_proj_students += "<td>online-only</td>"
            _cur_proj_sep = "</tr><tr><td>"
        tmp_row = tmp_row.replace("{{PARTICIPANTS_LIST}}", _cur_proj_students)
    else:
        tmp_row = tmp_row.replace("{{PARTICIPANTS_LIST}}", "")

    proj_select += tmp_row
    
#    proj_select += project_toc_row.format(projID, projID, project_data[projID]['name']);
    user_rows = ""
    no = 1

    for student_row in sorted(project_data[projID]['students'], key=lambda student_row: (student_row['choice'], -student_data[student_row['id']]['average'], student_row['id'])):
        # display students according to (choice (asc), average value (desc), ID (asc))
        id = student_row['id']
        row = project_user_row
        row = row.replace("{{I}}", "{0}".format(no))
        row = row.replace("{{NAME}}", user_data[id]['Name'])
        row = row.replace("{{ID}}", user_data[id]['ID'])
        row = row.replace("{{COUNTRY}}", user_data[id]['Country'])
        row = row.replace("{{GENDER}}", user_data[id]['Gender'])
        row = row.replace("{{AGE}}", user_data[id]['Age (years)'])
        row = row.replace("{{CHOICE}}", student_row['choice'])
        row = row.replace("{{OVERALL}}", student_row['choice'])
        row = row.replace("{{HTML_FILENAME}}", user_data[id]['link_application'])
        row = row.replace("{{EVALUATION_HTML_LINK_1}}", student_data[id]['evaluation_detail_file'][0])
        row = row.replace("{{EVALUATION_HTML_LINK_2}}", student_data[id]['evaluation_detail_file'][1])
        row = row.replace("{{REVIEWER_1}}", student_data[id]['reviewer'][0])
        row = row.replace("{{REVIEWER_2}}", student_data[id]['reviewer'][1])
        row = row.replace("{{OVERALL_COMMENT_1}}", student_data[id]['overall_comment'][0])
        row = row.replace("{{OVERALL_COMMENT_2}}", student_data[id]['overall_comment'][1])

        if user_data[id]['selected'] in ['invalid', 'withdrawn', 'declined']:
            style = "registrant_withdrawn"
        elif user_data[id]['selected'].startswith("%d" % projID):
            # current student is selected for the current project
            style = "registrant_selected"
            if user_data[id]['tentative']:
                style = "registrant_selected_tentative"
        elif user_data[id]['selected']:
            # current student is selected for a different project
            style = "registrant_selected_other"
        else:
            # ordinary row
            style = ""
        row = row.replace("{{REGISTRANT_SELECTED}}", style)

        for part in ['motivation','ambasador','technical']:
            # add all parts
            html_fld = part.upper()
            #print(student_data[id].keys())
            #print(part in student_data[id])
            row = row.replace("{{"+ html_fld +"_P1}}", "{0}".format(student_data[id][part]['p'][0]))
            row = row.replace("{{"+ html_fld +"_P2}}", "{0}".format(student_data[id][part]['p'][1]))
            row = row.replace("{{"+ html_fld +"_COMMENT_P1}}", "{0}".format(student_data[id][part]['comment'][0]))
            row = row.replace("{{"+ html_fld +"_COMMENT_P2}}", "{0}".format(student_data[id][part]['comment'][1]))
    
            if student_data[id][part]['avg'] > 0:
                row = row.replace("{{"+ html_fld +"_AVG}}", "{0:.2f}".format(student_data[id][part]['avg']))
            else:
                row = row.replace("{{"+ html_fld +"_AVG}}", "")
            
        if student_data[id]['average'] > 0:
            row = row.replace("{{AVERAGE_P}}", "{0:.2f}".format(student_data[id]['average']))
        else:
            row = row.replace("{{AVERAGE_P}}", "")

        for prefNo in range(1,4):
            # display all preferences
            row = row.replace("{{PREFERENCE_" + "{0}".format(prefNo) +"_SHORT_COMPULSORY}}", 
                              "{0}<br>{1}".format(student_data[id]['preference'][0][prefNo-1][0], student_data[id]['preference'][1][prefNo-1][0]))
            row = row.replace("{{PREFERENCE_" + "{0}".format(prefNo) +"_SHORT_DESIRABLE}}", 
                              "{0}<br>{1}".format(student_data[id]['preference'][0][prefNo-1][1], student_data[id]['preference'][1][prefNo-1][1]))
            row = row.replace("{{PREFERENCE_" + "{0}".format(prefNo) +"_COMPULSORY}}", 
                              "{0}: {1}\n{2}: {3}".format(student_data[id]['reviewer'][0], student_data[id]['preference'][0][prefNo-1][0], 
                                                            student_data[id]['reviewer'][1], student_data[id]['preference'][1][prefNo-1][0]))
            row = row.replace("{{PREFERENCE_" + "{0}".format(prefNo) +"_DESIRABLE}}", 
                              "{0}: {1}\n{2}: {3}".format(student_data[id]['reviewer'][0], student_data[id]['preference'][0][prefNo-1][1], 
                                                            student_data[id]['reviewer'][1], student_data[id]['preference'][1][prefNo-1][1]))

        user_rows += row
        no += 1

    proj_row = proj_row.replace("{{REGISTRANT_DATA}}", user_rows)
    proj_rows += proj_row

#print(project_data)
#print(proj_select)
#print(proj_rows)

index_data = index_data.replace("{{PROJECT_LIST_AND_SELECTED_PARTICIPANTS}}", proj_select)
content_projects = proj_rows


#
# display country statistics: all + selected registrants + percents
country_rows = ""
country_list_sorted = sorted(country_data)

for ctryName in country_list_sorted:
    # loop over all countries
    row = ""
    perc = 100 * country_data[ctryName]['selected'] * 1.0 / country_data[ctryName]['all']
    country_rows += "<tr><td>{0}</td><td class='id'>{1}</td><td class='id'>{2}</td><td class='id'>{3:.1f}</td></tr>".format(
                            ctryName, country_data[ctryName]['all'], country_data[ctryName]['selected'], perc)

index_data = index_data.replace("{{COUNTRY_PARTICIPANTS_LIST}}", country_rows)

# layout of registrant data + scores of evaluation + average scores
user_avg = {}

for id in user_data:
    # loop over usr data and create {key: avg} for sorting
    user_avg.update({id: student_data[id]['average']})
    
# now sort it
user_sorted = Counter(user_avg)

rows = ""
no = 1
for cell in user_sorted.most_common():
    # loop over usr data and create registrant data
    id = cell[0]
    row = person_row
    row = row.replace("{{I}}", "{0}".format(no))
    row = row.replace("{{REGISTRANT_NAME}}", user_data[id]['Name'])
    row = row.replace("{{COUNTRY}}", user_data[id]['Country'])
    row = row.replace("{{GENDER}}", user_data[id]['Gender'])
    row = row.replace("{{AGE}}", user_data[id]['Age (years)'])
    row = row.replace("{{REGISTRANT_ID}}", user_data[id]['ID'])
    row = row.replace("{{HTML_FILENAME}}", user_data[id]['link_application'])
    row = row.replace("{{REVIEWER_1}}", student_data[id]['reviewer'][0])
    row = row.replace("{{REVIEWER_2}}", student_data[id]['reviewer'][1])
    row = row.replace("{{OVERALL_COMMENT_1}}", student_data[id]['overall_comment'][0])
    row = row.replace("{{OVERALL_COMMENT_2}}", student_data[id]['overall_comment'][1])
    project_list_tmp = ""
    sep = ""
    
    if user_data[id]['selected'] in ['invalid', 'withdrawn', 'declined']:
        style = "registrant_withdrawn"
    elif user_data[id]['selected']:
        # current student is selected for project; display it in special way
        style = "registrant_selected"
        if user_data[id]['tentative']:
            style = "registrant_selected_tentative"
    else:
        # ordinary row
        style = ""
    row = row.replace("{{REGISTRANT_SELECTED}}", style)

    for fldName in ['Choice1ID', 'Choice2ID', 'Choice3ID']:
        # get all three projects and first add all user's first choise, then second and then third choice
        projID = user_data[id][fldName]
        if projID:
            other = user_data[id]['selected'] and not user_data[id]['selected'].startswith("%d" % projID)
            project_list_tmp += sep
            if other:
                project_list_tmp += "("
            project_list_tmp += "<a href='#project_%(projID)s'>%(projID)s</a>" % {'projID': projID}
            if other:
                project_list_tmp += ")"
            sep = ", "

    row = row.replace("{{PROJECT_ID_LIST}}", project_list_tmp)

    for part in ['motivation','ambasador','technical']:
        # add all parts
        html_fld = part.upper()
        row = row.replace("{{"+ html_fld +"_P1}}", "{0}".format(student_data[id][part]['p'][0]))
        row = row.replace("{{"+ html_fld +"_P2}}", "{0}".format(student_data[id][part]['p'][1]))
        row = row.replace("{{"+ html_fld +"_COMMENT_P1}}", "{0}".format(student_data[id][part]['comment'][0]))
        row = row.replace("{{"+ html_fld +"_COMMENT_P2}}", "{0}".format(student_data[id][part]['comment'][1]))

        if student_data[id][part]['avg'] > 0:
            row = row.replace("{{"+ html_fld +"_AVG}}", "{0:.2f}".format(student_data[id][part]['avg']))
        else:
            row = row.replace("{{"+ html_fld +"_AVG}}", "")
        
    if student_data[id]['average'] > 0:
        row = row.replace("{{AVERAGE_P}}", "{0:.2f}".format(student_data[id]['average']))
    else:
        row = row.replace("{{AVERAGE_P}}", "")

    for prefNo in range(1,4):
        # display all preferences
        row = row.replace("{{PREFERENCE_" + "{0}".format(prefNo) +"_SHORT_COMPULSORY}}", 
                          "{0}<br>{1}".format(student_data[id]['preference'][0][prefNo-1][0], student_data[id]['preference'][1][prefNo-1][0]))
        row = row.replace("{{PREFERENCE_" + "{0}".format(prefNo) +"_SHORT_DESIRABLE}}", 
                          "{0}<br>{1}".format(student_data[id]['preference'][0][prefNo-1][1], student_data[id]['preference'][1][prefNo-1][1]))
        row = row.replace("{{PREFERENCE_" + "{0}".format(prefNo) +"_COMPULSORY}}", 
                          "{0}: {1}\n{2}: {3}".format(student_data[id]['reviewer'][0], student_data[id]['preference'][0][prefNo-1][0], 
                                                        student_data[id]['reviewer'][1], student_data[id]['preference'][1][prefNo-1][0]))
        row = row.replace("{{PREFERENCE_" + "{0}".format(prefNo) +"_DESIRABLE}}", 
                          "{0}: {1}\n{2}: {3}".format(student_data[id]['reviewer'][0], student_data[id]['preference'][0][prefNo-1][1], 
                                                        student_data[id]['reviewer'][1], student_data[id]['preference'][1][prefNo-1][1]))

    rows += row
    no += 1
    
    
content_registrants = registrant_list.format(rows)

# add persons list into "index" file content
content = index_data
content = content.replace("{{CONTENT_PROJECTS}}", content_projects)
content = content.replace("{{CONTENT_REGISTRANTS}}", content_registrants)
save_content("evaluation.html", skeleton, "Summer of HPC {0} - Project evaluation results".format(SoHPC_year), generation_date, content)

students_csv = ""
for id in user_data:
    ud = user_data[id].copy()
    ud.update({'average': student_data[id]['average']})
    students_csv += "%(ID)3s, %(average)4.2f, %(Choice1ID)4d, %(Choice2ID)4d, %(Choice3ID)4d, %(selected)6s, %(Name)s, %(Country)s, %(Gender)s, %(Age (years))s\n" % ud
with open("students.csv", "w") as f:
    f.write(students_csv)

print("All done!")