#!/usr/bin/env bash
# ./scripts/verify_ir.sh test/test_case/simple_add.sy --run

set -euo pipefail

if [[ $# -lt 1 || $# -gt 3 ]]; then
  echo "用法: $0 <input.sy> [output_dir] [--run]" >&2
  exit 1
fi

input=$1
out_dir="test/test_result/ir"
run_exec=false
input_dir=$(dirname "$input")

shift
while [[ $# -gt 0 ]]; do
  case "$1" in
    --run)
      run_exec=true
      ;;
    *)
      out_dir="$1"
      ;;
  esac
  shift
done

if [[ ! -f "$input" ]]; then
  echo "输入文件不存在: $input" >&2
  exit 1
fi

compiler="./build/bin/compiler"
if [[ ! -x "$compiler" ]]; then
  echo "未找到编译器: $compiler ，请先构建（如: mkdir -p build && cd build && cmake .. && make -j）" >&2
  exit 1
fi

mkdir -p "$out_dir"
base=$(basename "$input")
stem=${base%.sy}
out_file="$out_dir/$stem.ll"
stdin_file="$input_dir/$stem.in"
expected_file="$input_dir/$stem.out"
"$compiler" --emit-ir "$input" > "$out_file"
echo "IR 已生成: $out_file"

if [[ "$run_exec" == true ]]; then
  if ! command -v llc >/dev/null 2>&1; then
    echo "未找到 llc，无法运行 IR。请安装 LLVM。" >&2
    exit 1
  fi
  if ! command -v clang >/dev/null 2>&1; then
    echo "未找到 clang，无法链接可执行文件。请安装 LLVM/Clang。" >&2
    exit 1
  fi
  obj="$out_dir/$stem.o"
  exe="$out_dir/$stem"
  stdout_file="$out_dir/$stem.stdout"
  actual_file="$out_dir/$stem.actual.out"
  llc -filetype=obj "$out_file" -o "$obj"
  clang "$obj" -o "$exe"
  echo "运行 $exe ..."
  set +e
  if [[ -f "$stdin_file" ]]; then
    "$exe" < "$stdin_file" > "$stdout_file"
  else
    "$exe" > "$stdout_file"
  fi
  status=$?
  set -e
  cat "$stdout_file"
  echo "退出码: $status"
  {
    cat "$stdout_file"
    if [[ -s "$stdout_file" ]] && (( $(tail -c 1 "$stdout_file" | wc -l) == 0 )); then
      printf '\n'
    fi
    printf '%s\n' "$status"
  } > "$actual_file"

  if [[ -f "$expected_file" ]]; then
    if diff -u "$expected_file" "$actual_file"; then
      echo "输出匹配: $expected_file"
    else
      echo "输出不匹配: $expected_file" >&2
      echo "实际输出已保存: $actual_file" >&2
      exit 1
    fi
  else
    echo "未找到预期输出文件，跳过比对: $expected_file"
  fi
fi
