#!/bin/env bash
# adapted from tree-sitter-typescript/script/parse-examples

set -Eeu -o pipefail
shopt -s inherit_errexit

this_file="${BASH_SOURCE[0]}"
if [ "${this_file::1}" != '/' ]; then
  this_file="$PWD/$this_file"
fi

this_dir="${this_file%/*}"
project_root="${this_dir%/*}"
sources_dir="$project_root/test/sources"

cd "$project_root"

clone_repo() {
  local owner=$1
  local name=$2
  local sha=$3
  local path="$sources_dir/$name"

  if [ -d "$path" ]; then
    pushd "$path" > /dev/null
    if [ "$(git rev-parse HEAD 2>/dev/null)" == "$sha"  ]; then
      popd > /dev/null
      return
    else
      popd > /dev/null
      rm -rf "$path"
      echo "Updating $owner/$name to $sha"
    fi
  else
    echo "Cloning $owner/$name"
  fi

  mkdir -p "$path"
  pushd "$path" > /dev/null
  git init --quiet
  git remote add origin "https://github.com/$owner/$name"
  git pull --quiet --ff-only --depth 1 origin "$sha"
  popd > /dev/null
}

# zig 0.10.1 -> https://github.com/ziglang/zig/releases/tag/0.10.1
clone_repo ziglang zig b57081f039bd3f8f82210e8896e336e3c3a6869b
# the following projects should be compatible with the zig version above
# the commits were chosen through `git log -1 --until="$ZIG_RELEASE_DATE"`
clone_repo tigerbeetledb tigerbeetle eff4158fb7f39f7557f646d7eb1bde39d8459d22
clone_repo zigtools zls fa5828496eb8b554ec69ed0beff7a9edcb53411a
clone_repo oven-sh bun cd5f2ab11fb33e805271b9b48711f3f592f30b0f

failures_file="$this_dir/known-parsing-failures.txt"
inexistent_failures=()
incorrect_failures=()
known_failures=()
if [ -e "$failures_file" ]; then
  while IFS= read -r line; do
    if [[ "$line" =~ [^[:space:]] ]]; then
      full_path="$sources_dir/$line"
      if [ -e "$full_path" ]; then
        if tree-sitter parse -q "$full_path" &>/dev/null; then
          incorrect_failures+=("$line")
        else
          known_failures+=("$sources_dir/$line")
        fi
      else
        inexistent_failures+=("$line")
      fi
    fi
  done < "$failures_file"
fi
if [ ${#incorrect_failures[*]} -gt 0 ]; then
  >&2 echo "Some files can be parsed without errors, but they are listed in $failures_file. Please remove those lines from $failures_file and try again:"
  >&2 printf -- "- %s\n" "${incorrect_failures[@]}"
  exit 1
fi
if [ ${#inexistent_failures[*]} -gt 0 ]; then
  >&2 echo "The following files could not be found in $sources_dir. Please remove those lines from $failures_file and try again:"
  >&2 printf -- "- %s\n" "${inexistent_failures[@]}"
  exit 1
fi

while IFS= read -r line; do
  for known_failure in "${known_failures[@]}"; do
    if [ "$known_failure" == "$line" ]; then
      continue 2
    fi
  done
  parse_args+=("$line")
done < <(
  find "$sources_dir" \
    -name "*.zig" \
    -not -path "$sources_dir/zig/test/cases/compile_errors/**"
)
if [ ${#parse_args[*]} -eq 0 ]; then
  >&2 echo "No files found to parse"
  exit 1
fi

echo $'\n'"The following files will be parsed:"
printf -- "- %s\n" "${parse_args[@]}"
echo $'\n'

tree-sitter parse -q "${parse_args[@]}"
