export function processData () {
  const folderInput = document.querySelector("#folder");
  const header = [
    "submissionid",
    "file",
    "filesize",
    "timestamp",
    "humandate",
    "grade",
    "userid",
    "exerciseid",
  ];

  function generateSubCode (algorithmInIlm) {
    window.program_obj.functions = JSON.parse(algorithmInIlm).functions;
    window.program_obj.globals = JSON.parse(algorithmInIlm).globals;
    return window.ivprogCore.generateCode();
  }

  function prepareData (map, submission) {
    if (!submission) {
      return map;
    }
    const exercID = submission["exerciseid"];
    const studentID = submission["userid"];
    let exercMap = null;
    if (map.has(exercID)) {
      exercMap = map.get(exercID);
    } else {
      exercMap = new Map();
      map.set(exercID, exercMap);
    }
    if (exercMap.has(studentID)) {
      exercMap.get(studentID).push(submission);
    } else {
      exercMap.set(studentID, [submission]);
    }
    return map;
  }

  folderInput.addEventListener("change", async () => {
    const files = Array.from(folderInput.files);
    const idx = files.find((f) => f.name == "index.csv");
    const folderName = idx.webkitRelativePath.replace(idx.name, "");
    //console.debug(idx);
    //console.debug(folderName);
    const data = await idx.text();
    //console.debug(data);
    const csvEntries = data
      .split("\n")
      .slice(1)
      .filter((line) => line.length > 0)
      .map((line) => line.split(","))
      .map((vec) => {
        const obj = {};
        vec.forEach((val, i) => (obj[header[i]] = val));
        return obj;
      });
    //console.debug(csvEntries);
    const blockExercMap = csvEntries.reduce(prepareData, new Map());
    //console.log(Array.from(blockExercMatrix.entries()));
    const getFilePath = async function (submission) {
      const path = `${folderName}${submission["file"]}`;
      const file = files.find((f) => f.webkitRelativePath == path);
      const text = await file.text();
      return text;
    };
    const matrix = {};
    let counter = 0;
    blockExercMap.forEach((studentsMap, exercID) => {
      const column = [];
      studentsMap.forEach(async (submissions, studentID) => {
        submissions = submissions.sort((a, b) => {
          return parseInt(a["timestamp"]) - parseInt(b["timestamp"]);
        });
        counter++;
        submissions.forEach(async (submission, index, array) => {
          counter++;
          const student = {};
          student["grade"] = Math.max(0, parseFloat(submission["grade"]));
          student["timestamp"] = parseInt(submission["timestamp"]);
          student["student_id"] = studentID;
          student["TES"] = 0;
          student["DES"] = 0;
          student["D/T"] = 0;
          let previousCode = "";
          if (index > 0) {
            student["TES"] =
              parseInt(submission["timestamp"]) -
              parseInt(array[index - 1]["timestamp"]);
            const previousFile = await getFilePath(array[index - 1]);
            const previous = window.ivprogCore
              .prepareActivityToStudentHelper(previousFile)
              .getOrElse(1);
            if (previous == 1) {
              console.error(
                `A submission from ${studentID} to ${exercID} is invalid`
              );
              return;
            }
            previousCode = generateSubCode(previous.algorithmInIlm);
          }
          const currentFile = await getFilePath(submission);
          const current = window.ivprogCore
            .prepareActivityToStudentHelper(currentFile)
            .getOrElse(2);
          if (current == 2) {
            console.error(
              `A submission from ${studentID} to ${exercID} is invalid`
            );
            return;
          }
          const currentCode = generateSubCode(current.algorithmInIlm);
          if (previousCode === "") {
            const logs = JSON.parse(currentFile.split("::logs::")[1]);
            const event = logs[0];
            if (event == null) {
              // empty submission
              student["TES"] = 0;
            } else if (event.length === 4) {
              student["TES"] =
                parseInt(submission["timestamp"]) -
                Math.floor(parseInt(event[2]) / 1000);
            } else {
              student["TES"] =
                parseInt(submission["timestamp"]) -
                Math.floor(parseInt(event[1]) / 1000);
            }
          }
          student["DES"] = window.ivprogCore.levenshteinDistance(
            previousCode,
            currentCode
          );
          const ratio =
            student["TES"] === 0 ? 0 : student["DES"] / student["TES"];
          student["D/T"] = isNaN(ratio) ? 0 : ratio;
          column.push(student);
          counter--;
        });
        counter--;
      });
      matrix[exercID] = column;
    });
    function download (file, text) {
      //creating an invisible element
      const element = document.createElement("a");
      element.setAttribute(
        "href",
        "data:text/plain," + encodeURIComponent(text)
      );
      element.setAttribute("download", file);
      element.innerHTML = file;
      element.classList.add("ui", "primary", "button");

      // Above code is equivalent to
      // <a href="path of file" download="file name">

      document.querySelector("#downloads").appendChild(element);
    }
    function getExercHeader (id) {
      const props = ["TES", "DES", "grade", "D/T", "timestamp"];
      return props.reduce((acc, prop) => acc + `${id}_${prop},`, "");
    }
    const id = setInterval(() => {
      if (counter == 0) {
        clearInterval(id);
        for (const exercID in matrix) {
          let csv = "";
          let firstLine = "student_id,";
          firstLine += getExercHeader(exercID);
          for (const submission of matrix[exercID]) {
            csv += `${submission["student_id"]},`;
            csv += `${submission["TES"]},`;
            csv += `${submission["DES"]},`;
            csv += `${submission["grade"]},`;
            csv += `${submission["D/T"]},`;
            csv += `${submission["timestamp"]}`;
            csv += "\n";
          }
          download(`${exercID}.csv`, `${firstLine}\n${csv}`);
        }
      }
    }, 1000);
  });
}
