#!/bin/sh

OUT_SRC=src/tests_autogen.c
OUT_INC=include/tests_autogen.h
DATE=$(date)

# ---

gen_src_head() {
  cat > $OUT_SRC << EOF
// Generated on $DATE by $USER
//
#include "mgos.h"
#include "$(basename $OUT_INC)"

EOF
}

gen_src_body() {
  echo "GEN $OUT_SRC"
  (
    for n in $*; do
      echo "extern uint32_t test_${n}_period_ms;"
    done
    echo ""
  for func in create destroy; do
    echo "bool tests_${func}(void) {"
    echo "  uint32_t total=0, success=0;"
    for n in $*; do
      cat << EOF
  if (!test_${n}_${func}()) {
    LOG(LL_ERROR, ("Could not $func test $n"));
  } else {
    success++;
  }
  total++;

EOF
    done
    cat << EOF
  return (total == success);
}

EOF
  done

  cat << EOF
bool tests_run(void) {
  double now;
  uint32_t total, success;
EOF
  for n in $*; do
    echo "  static double next_${n}_run = 0;"
  done
  cat << EOF
  for (;;) {
    now = mg_time();
EOF
  for n in $*; do
    cat << EOF
    if (now > next_${n}_run) {
      if (test_${n}_run()) success++;
      next_${n}_run = now + (test_${n}_period_ms/1000.f);
      total++;
    }
EOF
  done

  cat << EOF
    mgos_usleep(1000);
  }
  return (total == success);
}
 
EOF
  ) >> $OUT_SRC
}

gen_src_tail() {
  cat >> $OUT_SRC << EOF
EOF
}

gen_inc_head() {
  cat > $OUT_INC << EOF
// Generated on $DATE by $USER
//
#pragma once
#include "mgos.h"

// Master test prototypes (called from main.c)
bool tests_create(void);
bool tests_run(void);
bool tests_destroy(void);

EOF
}

gen_inc_body() {
  echo "GEN $OUT_INC"
  for n in $*; do
    cat >> $OUT_INC << EOF
// Test suite "$n"
bool test_${n}_create(void);
bool test_${n}_run(void);
bool test_${n}_destroy(void);

EOF
  done
}

gen_inc_tail() {
  cat >> $OUT_INC << EOF
EOF
}

gen_inc_head
gen_src_head

for f in tests/*.c; do
  base=$(basename $f | cut -f1 -d'.')
  echo "CHK $base in $f"
  egrep -q "test_${base}_enabled.*true" $f && base_list="$base_list $base"
done

gen_inc_body $base_list
gen_src_body $base_list

gen_inc_tail
gen_src_tail