#!/usr/bin/env bash

# Create a test dashboard

set -uo pipefail

export GITHUB_REPOSITORY=${GITHUB_REPOSITORY:-"nigelhorne/App-Test-Generator"}
PATH="./bin:$PATH"	# Prefer programs in our repo, to ensure the latest version where applicable

set -e

# --- Step 0: Cleanup old data ---
echo "Cleaning up old coverage, LCSAJ, and mutation data..."
# Preserve LCSAJ hits across runs, same as mutation.json
if [ -f cover_html/lcsaj_hits.json ]; then
	cp cover_html/lcsaj_hits.json /tmp/lcsaj_hits_prev.json
fi
rm -rf cover_db coverage lcsaj mutation_html cover_html t/tmp_*.t

# --- Step 1: Build blib if needed ---
echo "Building blib..."
perl Makefile.PL && make

export PERL5OPT='-Ilib'

# --- Step 2: Run tests under Devel::Cover ---
echo "Running tests with Devel::Cover..."
PERL5OPT="-MDevel::Cover=-db,cover_db,-select,^lib/" \
	prove -l $(find t -maxdepth 1 -name '*.t' ! -name 'mutant_*.t' | sort)
	cover -outputdir cover_html -select '^lib/'

# --- Step 3: Generate JSON coverage report ---
echo "Generating JSON coverage report..."
cover -report json -outputdir cover_html

# --- Step 4: Export LCSAJ targets (absolute paths) ---
echo "Finding LCSAJ targets..."
export LCSAJ_TARGETS=$(
  { find lib -name '*.pm' -exec realpath {} \; ;
    find blib/lib -name '*.pm' -exec realpath {} \; ; } \
  | tr '\n' ':' | sed 's/:$//'
)

set +e

# --- Step 5: Run tests again under LCSAJ runtime ---
echo "Recording LCSAJ hits..."
if [ -z "$LCSAJ_TARGETS" ]; then
	echo "ERROR: LCSAJ_TARGETS is empty - no .pm files found" >&2
	exit 1
fi
echo "LCSAJ_TARGETS=$LCSAJ_TARGETS"
mkdir -p coverage
# PERL5LIB must be set separately from PERL5OPT so lib/ is in @INC when the debugger module initialises, before -Mblib takes effect
PERL5LIB="./lib:./blib/lib" PERL5OPT="-d:App::Test::Generator::LCSAJ::Runtime" prove -l t

# --- Step 5b: Merge per-process LCSAJ hit files ---
echo "Merging LCSAJ hits..."
perl -MJSON::MaybeXS -MFile::Slurp -e '
	my %merged;
	for my $f (glob("cover_html/lcsaj_hits/hits_*.json")) {
		my $data = eval { decode_json(read_file($f)) } or next;
		for my $file (keys %$data) {
			for my $line (keys %{$data->{$file}}) {
				$merged{$file}{$line} += $data->{$file}{$line};
			}
		}
	}
	write_file("cover_html/lcsaj_hits.json", encode_json(\%merged));
	printf "Merged %d files\n", scalar keys %merged;
'

# --- Step 5c: Verify LCSAJ hits ---
echo "Checking LCSAJ hits..."
# Merge previous LCSAJ hits for files not in this run
if [ -f /tmp/lcsaj_hits_prev.json ]; then
	perl -MJSON:MaybeXS -MFile::Slurp -e '
		my $prev = decode_json(read_file("/tmp/lcsaj_hits_prev.json"));
		my $curr = -f "cover_html/lcsaj_hits.json"
			? decode_json(read_file("cover_html/lcsaj_hits.json"))
			: {};
		# curr entries take priority; prev fills in missing files
		my %merged = (%{$prev}, %{$curr});
		write_file("cover_html/lcsaj_hits.json", encode_json(\%merged));
	'
fi
if [ -f cover_html/lcsaj_hits.json ]; then
	echo "lcsaj_hits.json exists, size $(wc -c < cover_html/lcsaj_hits.json) bytes"
	perl -MJSON::MaybeXS -MFile::Slurp -e '
		my $h = decode_json(read_file("cover_html/lcsaj_hits.json"));
		for my $f (sort keys %$h) {
			printf "%s: %d lines hit\n", $f, scalar keys %{$h->{$f}};
		}
	'
else
	echo "lcsaj_hits.json MISSING"
fi

# --- Step 5d: Diagnose LCSAJ hit file sources ---
echo "Diagnosing LCSAJ hit file sources..."
echo "Per-process hit files in cover_html/lcsaj_hits/:"
ls -la cover_html/lcsaj_hits/ 2>/dev/null || echo "  Directory missing or empty"
echo "Searching entire workspace for hits_*.json files:"
find . -name 'hits_*.json' 2>/dev/null || echo "  None found"
echo "Merged lcsaj_hits.json content (first 500 chars):"
head -c 500 cover_html/lcsaj_hits.json 2>/dev/null || echo "  File missing"
echo "LCSAJ_TARGETS value:"
echo "${LCSAJ_TARGETS:0:500}"

# --- Step 6: Run mutation analysis ---
echo "Running mutation analysis..."
mkdir -p mutation_html/lib cover_html
test-generator-mutate \
	-v \
	--lib lib \
	--tests t \
	--json mutation.json \
	--mutation_level=fast \
	--cover_json cover_html/cover.json \
	--lcsaj_root cover_html/mutation_html/lib \
	--changed_only \
	--lcsaj_hits cover_html/lcsaj_hits.json < /dev/null
	# --min-score 85

set -e

# --- Step 7: Create the test dashboard ---
# --generate_mutant_tests=t writes TODO stubs for surviving mutants.
# --generate_test=mutant attempts runnable YAML schemas for NUM_BOUNDARY
# survivors via SchemaExtractor where confidence is sufficient.
# --generate_fuzz augments existing t/conf/ schemas with boundary values
# from surviving mutants, writing timestamped copies for t/fuzz.t.
echo "Creating the LCSAJ files..."
perl -Ilib $(which instrument-modules)
echo "Creating the dashboard..."
test-generator-index \
	--generate_mutant_tests=t \
	--generate_test=mutant \
	--generate_fuzz

echo "Done! Check cover_html/index.html locally, or https://nigelhorne.github.io/${GITHUB_REPOSITORY#*/}/coverage/ when deployed."
