#!/bin/sh
# Smoke test for the installed leak_tracker library; runs offline.
set -eu

work=$(mktemp -d)
export HOME="$work"
trap 'rm -rf "$work"' EXIT INT TERM

DART=$(command -v dart 2>/dev/null || true)
[ -n "$DART" ] || DART=/usr/lib/dart/bin/dart

# Each package gets the language version its own pubspec asks for.
json=""
add_pkg() {
	dir="/usr/share/dart/packages/$1"
	lv=$(LC_ALL=C grep -E "^  sdk:" "$dir/pubspec.yaml" 2>/dev/null | LC_ALL=C grep -oE "[0-9]+\.[0-9]+" | head -1)
	[ -n "$lv" ] || lv=3.0
	[ -z "$json" ] || json="$json,"
	json="$json{\"name\":\"$1\",\"rootUri\":\"file://$dir\",\"packageUri\":\"lib/\",\"languageVersion\":\"$lv\"}"
}


# Reference every installed Dart package so transitive imports resolve.
for dir in /usr/share/dart/packages/*/; do
	[ -d "$dir" ] || continue
	add_pkg "$(basename "$dir")"
done

mkdir -p "$work/.dart_tool"
cat > "$work/.dart_tool/package_config.json" <<JSON
{"configVersion":2,"packages":[$json]}
JSON

cat > "$work/main.dart" <<'DART'
import 'dart:async';

import 'package:leak_tracker/leak_tracker.dart';

WeakReference<Object> makeGarbage() => WeakReference<Object>(Object());

void main() async {
  if (LeakType.values.isEmpty) {
    throw StateError('LeakType has no values');
  }

  const config = LeakDiagnosticConfig(
    collectStackTraceOnStart: true,
    collectRetainingPathForNotGCed: true,
  );
  final copy = config.copyWith(collectStackTraceOnDisposal: true);
  if (!copy.collectStackTraceOnStart ||
      !copy.collectStackTraceOnDisposal ||
      !copy.collectRetainingPathForNotGCed) {
    throw StateError('LeakDiagnosticConfig.copyWith lost a flag');
  }

  // forceGC must really collect: an unreachable object has to be gone.
  final weak = makeGarbage();
  await forceGC(fullGcCycles: 10);
  if (weak.target != null) {
    throw StateError('forceGC did not collect the unreachable object');
  }

  print('leak_tracker smoke test passed');
}
DART

cd "$work"
"$DART" run main.dart
