#!/bin/sh

# Main ├────────────────────────────────────────────────────────────────────────

main() {
  number_tests=0
  number_failures=0
  dirs="$@"
  test=$(pwd)
  work=$(mktemp --directory)
  cp -R . $work
  trap "rm -R $work" EXIT
  for dir in $(find $dirs -type d); do
    cd $test/$dir;
    test_files=$(find * -name out -o -name selections -o -name state)
    cd $work/$dir;
    indent="$(echo "${dir}/" | sed "s|[^/]*/\+|  |g")"
    name=$(basename $PWD)
    if ! test -e cmd; then
      echo "$indent$name"
    else
      number_tests=$(($number_tests + 1))
      touch in; cp in out
      kak_commands="
        set global autoreload yes
        try %{
        source rc
        }
        try %{
        exec '%s%\((.+?)\)<ret>i<del><del><esc>a<backspace><c-u><esc>'
        } \
        catch %{
        exec gg
        }
        exec '$(cat cmd)'
        eval -buffer *debug* write debug
        nop %sh{ IFS==
        echo \"\$kak_selections\"      > selections
        echo \"\$kak_selections_desc\" > state
        }
        write out
        quit!
      "
      kak out -n -e "$kak_commands"
      for expect in $test_files; do
        if cmp -s $test/$dir/$expect $expect; then
          echo "$indent$name" | colorize green normal
        else
          number_failures=$(($number_failures + 1))
          echo "$indent$name" | colorize red normal
          echo
          diff -u $test/$dir/$expect $expect | while read -r line; do
            first_character=$(echo "$line" | cut -b 1)
            color=$(match $first_character + green - red @ magenta none)
            echo "$line" | colorize $color normal
          done
          echo
          echo "debug buffer:" | colorize yellow normal
          cat debug
          echo
        fi
      done
    fi
  done
  if expr $number_failures > 0; then
    color=red
  else
    color=green
  fi
  echo
  echo Resume:
  echo $number_tests tests, $number_failures failures | colorize $color normal
}

# Utility ├─────────────────────────────────────────────────────────────────────

match() {
  expression="$1";
  shift
  while [ $# > 0 ]; do
    pattern="$1"
    shift
    value="$1"
    next="$1"
    default_value="$pattern"
    if [ -z "$next" ]; then
      echo $default_value
      return 1
    fi
    if [ "$expression" = "$pattern" ]; then
      echo "$value"
      return 0
    fi
    shift
  done
}

get_ansi_code() {
  color_name=${1:-none}
  style_name=${2:-none}
  case "$color_name" in
    none)    color_nr=00 ;;
    red)     color_nr=31 ;;
    green)   color_nr=32 ;;
    yellow)  color_nr=33 ;;
    magenta) color_nr=35 ;;
    *)       color_nr=00 ;;
  esac
  case "$style_name" in
    none) style_nr=00 ;;
    bold) style_nr=01 ;;
    *)    style_nr=00 ;;
  esac
  printf '\033[%s;%sm' $style_nr $color_nr
}

colorize() {
  text=$(cat)
  color_name=${1:-none}
  style_name=${2:-none}
  echo "$(get_ansi_code $color_name $style_name)$text$(get_ansi_code none none)"
}


main $@