#!/usr/bin/env bash

run() {
  printf '%s==>%s %s\n' "$(tput setaf 2)" "$(tput sgr0)" "$*"
  "$@"

  if (( $? )); then
    exit
  fi
}

compile-all() {
  mkdir -p bin

  for src in src/*.cpp; do
    bin=bin/${src#src/} bin=${bin%.cpp}.o

    if [[ ! -v CHECK_COMPILE ]] || "$CHECK_COMPILE" "$src" "$bin"; then
      run c++ "${CXXFLAGS[@]}" -c -o "$bin" "$src"
    fi
  done

  run c++ "${LDFLAGS[@]}" -o bin/chimney bin/*.o
}

set-default-flags() {
  CXXFLAGS=(-std=c++2a -Wall -Wextra -pedantic -O1 -I include)
  LDFLAGS=(-O1)
}

is-newer() {
  [[ $1 -nt "$2" ]]
}

cmd-make() {
  local {CXX,LD}FLAGS
  set-default-flags
  CHECK_COMPILE=is-newer compile-all
}

cmd-fresh() {
  local {CXX,LD}FLAGS
  set-default-flags
  compile-all
}

cmd-clean() {
  run rm -rf bin
}

declare -A opts

while (( $# )); do
  if [[ $1 = -- ]]; then
    shift
    break
  elif [[ $1 = -no-* ]]; then
    opts[${1#-no-}]=no
  elif [[ $1 = -*=* ]]; then
    key=${1#-} key=${key%%=*}
    opts[$key]=${1#*=}
  elif [[ $1 = -?* ]]; then
    opts[${1#-}]=yes
  else
    break
  fi

  shift
done

cmd=make

if (( $# )); then
  cmd=$1
  shift
fi

if ! hash cmd-"$cmd" 2>/dev/null; then
  printf 'Unknown command %s%s%s\n' "$(tput setaf 1)" "$cmd" "$(tput sgr0)" >&2
  exit
fi

cmd-"$cmd" "$@"