#!/bin/sh

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

main() {
  number_tests=0
  number_failures=0
  dirs="${@:-.}"
  test=$(pwd)
  work=$(mktemp -d /tmp/kak-tests.XXXXXXXX)
  cp -R . $work
  trap "rm -R $work" EXIT
  for dir in $(find $dirs -type d); do
    cd $test/$dir;
    test_files=$(ls out selections state 2>/dev/null)
    cd $work/$dir;
    indent="$(echo "${dir}/" | sed -e '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%\(\K[^)]+<ret><c-s>ld<a-t>(hHdi<c-u><esc><c-o>'
        } \
        catch %{
        exec gg
        }
        exec '$(cat cmd | sed -e s/\'/\\\\\'/g)'
        eval -buffer *debug* write debug
        nop %sh{ IFS==
        echo \"\$kak_selections\"      > selections
        echo \"\$kak_selections_desc\" > state
        }
        write out
        quit!
      "
      ${test}/../src/kak out -n -u -e "$kak_commands"
      retval=$?
      if [ $retval -ne 0 ]; then
          echo "Kakoune returned error $retval"
      fi
      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
  exit $number_failures
}

# 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 $@