#!/bin/bash

# to make the script fail safely
set -euo pipefail


out=${1:-output}

echo -e "" > $out

echo "The feedback for your submission for wordle.scala" >> $out
echo "" >> $out

# marks for main part 2

# compilation tests

function scala_compile {
  (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala -Xprint:parser "$1" 2> c$out 1> c$out)
}

# functional tests

function scala_assert {
  (ulimit -t 35; JAVA_OPTS="-Xmx1g" scala -nc -i "$1" -- "$2" -e "" 2> /dev/null 1> /dev/null)
}
 
# purity test
function scala_vars {
   (sed 's/immutable/ok/g' c$out > cb$out;
    egrep '\bvar\b|\breturn\b|\.par\.|\.par |ListBuffer|AtomicInteger|mutable|util.control|new Array' cb$out 2> /dev/null 1> /dev/null)
}


### compilation test

echo -e "wordle.scala runs?" >> $out

if (scala_compile wordle.scala)
then
    echo -e "  --> success" >> $out
    tsts0=$(( 0 ))
else
    echo -e "  --> SCALA DID NOT RUN wordle.scala\n" >> $out
    tsts0=$(( 1 )) 
fi

# var, .par return, ListBuffer test
#

if  [ $tsts0 -eq 0 ]
then
   echo -e "wordle.scala does not contain VARS, RETURNS etc?" >> $out
    
   if (scala_vars wordle.scala)
   then
      echo -e "  --> test failed\n" >> $out
      tsts=$(( 1 ))
   else
      echo -e "  --> success" >> $out
      tsts=$(( 0 )) 
   fi
else
   tsts=$(( 1 ))  
fi    


echo >> $out

### wordle tests: Task 1 (0.25%)

if [ $tsts -eq 0 ]
then
  echo "Task 1:"  >> $out
  echo "  val wordle_url = \"\"\"https://nms.kcl.ac.uk/christian.urban/wordle.txt\"\"\""     >> $out
  echo "  val secrets = get_wordle_list(wordle_url)"     >> $out
  echo "  secrets.length == 12972"    >> $out
  echo "  secrets.filter(_.length != 5) == Nil" >> $out
  echo "  get_wordle_list(wordle_url ++ \"2\") == Nil" >> $out
  

  if (scala_assert "wordle.scala" "wordle_test1.scala")
  then
      echo -e "  --> success\n" >> $out
  else
      echo -e "  --> one of the tests failed\n" >> $out
  fi
fi

### wordle tests: Task 2 (0.25%)

if [ $tsts -eq 0 ]
then
  echo "Task 2:"  >> $out  
  echo "  removeN(List(1,2,3,2,1), 3, 1) == List(1, 2, 2, 1)" >> $out
  echo "  removeN(List(1,2,3,2,1), 2, 1) == List(1, 3, 2, 1)" >> $out
  echo "  removeN(List(1,2,3,2,1), 1, 1) == List(2, 3, 2, 1)" >> $out
  echo "  removeN(List(1,2,3,2,1), 0, 1) == List(1, 2, 3, 2, 1)" >> $out
  echo "  removeN(List(\"a\", \"b\", \"b\"), \"b\", 1) == List(\"a\", \"b\")" >> $out
  echo "  removeN(List(\"b\", \"a\", \"b\", \"b\"), \"b\", 2) == List(\"a\", \"b\")" >> $out
  echo "  removeN(List(\"b\", \"a\", \"b\"), \"a\", 2) == List(\"b\", \"b\")" >> $out

  if (scala_assert "wordle.scala" "wordle_test2.scala")
  then
      echo -e "  --> success\n" >> $out
  else
      echo -e "  --> one of the tests failed\n" >> $out
  fi
fi

### wordle tests: Task 3 (1.5%)


if [ $tsts -eq 0 ]
then
  echo "Task 3:"  >> $out    
  echo "  pool(\"chess\", \"caves\").toSet == Set('h', 'e', 's')" >> $out
  echo "  pool(\"chess\", \"swiss\").toSet == Set('c', 'h', 'e')" >> $out

  if (scala_assert "wordle.scala" "wordle_test3a.scala") 
  then
      echo -e "  --> success\n" >> $out
  else
    echo -e "  --> one of the tests failed\n" >> $out
  fi
fi

if [ $tsts -eq 0 ]
then    
  echo "  score(\"chess\", \"caves\") == List(C, A, A, P, C)" >> $out
  echo "  score(\"doses\", \"slide\") == List(P, A, A, P, P)" >> $out
  echo "  score(\"chess\", \"swiss\") == List(A, A, A, C, C)" >> $out
  echo "  score(\"chess\", \"eexss\") == List(P, A, A, C, C)" >> $out
  echo "" >> $out
  echo "  val p = pool(\"chess\", \"caves\")"     >> $out
  echo "  aux(\"chess\".toList, \"caves\".toList, Nil) == List(C, A, A, A, C)" >> $out
  echo "  aux(\"chess\".toList, \"caves\".toList, p)   == List(C, A, A, P, C)" >> $out

  if (scala_assert "wordle.scala" "wordle_test3b.scala") 
  then
      echo -e "  --> success\n" >> $out
  else
    echo -e "  --> one of the tests failed\n" >> $out
  fi
fi

### wordle tests: Task 4 (0.5%)

if [ $tsts -eq 0 ]
then
  echo "Task 4:"  >> $out  
  echo "  iscore(\"chess\", \"caves\") == 21" >> $out
  echo "  iscore(\"chess\", \"swiss\") == 20" >> $out
 

  if (scala_assert "wordle.scala" "wordle_test4.scala")
  then
      echo -e "  --> success\n" >> $out
  else
      echo -e "  --> one of the tests failed\n" >> $out
  fi
fi

### wordle tests: Task 5 (1.5%)

if [ $tsts -eq 0 ]
then
  echo "Task 5:"  >> $out  
  echo "  val secrets = ..." >> $out
  echo "  evil(secrets, \"stent\").length == 1907" >> $out
  echo "  evil(secrets, \"hexes\").length == 2966" >> $out
  echo "  evil(secrets, \"horse\").length == 1203" >> $out
  echo "  evil(secrets, \"hoise\").length == 971" >> $out
  echo "  evil(secrets, \"house\").length == 1228" >> $out

  if (scala_assert "wordle.scala" "wordle_test5.scala")
  then
      echo -e "  --> success\n" >> $out
  else
      echo -e "  --> one of the tests failed\n" >> $out
  fi
fi

### wordle tests: Task 6 (1.0%)

if [ $tsts -eq 0 ]
then
  echo "Task 6:"  >> $out  
  echo "  val secrets = ..." >> $out
  echo "  frequencies(secrets)('y') == 0.9680234350909651" >> $out
  echo "  frequencies(secrets)('e') == 0.897286463151403"  >> $out
  echo "  frequencies(secrets)('z') == 0.9933086648165279" >> $out

  if (scala_assert "wordle.scala" "wordle_test6.scala")
  then
      echo -e "  --> success\n" >> $out
  else
      echo -e "  --> one of the tests failed\n" >> $out
  fi
fi

### wordle tests: Task 7 (1.0%)

if [ $tsts -eq 0 ]
then
  echo "Task 7:"  >> $out  
  echo "  val secrets = ..." >> $out
  echo "  ranked_evil(secrets, \"beats\") == List(\"fuzzy\")" >> $out
  echo "  ranked_evil(secrets, \"vitae\") == List(\"fuzzy\")" >> $out
  echo "  ranked_evil(secrets, \"bento\") == List(\"fuzzy\")" >> $out
  echo "  ranked_evil(secrets, \"belts\") == List(\"fuzzy\")" >> $out
  echo " " >> $out
  echo "  ranked_evil(secrets, \"abbey\") == List(\"whizz\")" >> $out
  echo "  ranked_evil(secrets, \"afear\") == List(\"buzzy\")" >> $out
  echo "  ranked_evil(secrets, \"zincy\") == List(\"jugum\")" >> $out
  echo "  ranked_evil(secrets, \"zippy\") == List(\"chuff\")" >> $out
  START=$(date +%s)
  if (scala_assert "wordle.scala" "wordle_test7.scala")
  then
      END=$(date +%s)
      DIFF=$(( $END - $START ))
      echo " This test ran for $DIFF seconds." >> $out
      echo -e "  --> success\n" >> $out
  else
      END=$(date +%s)
      DIFF=$(( $END - $START ))
      echo " This test ran for $DIFF seconds." >> $out
      echo -e "  --> one of the tests failed\n" >> $out
  fi
fi




