#!/bin/sh
# Runs a real HTTP request against a local server, entirely 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

# Register every installed Dart package so the import resolves.
mkdir -p "$work/.dart_tool"
{
    printf '{"configVersion":2,"packages":['
    first=1
    for dir in /usr/share/dart/packages/*/; do
        name=$(basename "$dir")
        [ "$first" -eq 1 ] || printf ','
        first=0
        printf '{"name":"%s","rootUri":"file:///usr/share/dart/packages/%s","packageUri":"lib/"}' "$name" "$name"
    done
    printf ']}\n'
} > "$work/.dart_tool/package_config.json"

# The client is synchronous, so the server has to live in another process.
cat > "$work/server.dart" <<'DART'
import 'dart:convert';
import 'dart:io';

Future<void> main() async {
  final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
  final body = utf8.encode('sync_http works');
  print(server.port);
  await for (final request in server) {
    // sync_http only accepts identity encoding, so set an explicit length.
    request.response
      ..statusCode = 200
      ..headers.contentType = ContentType.text
      ..contentLength = body.length
      ..add(body);
    await request.response.close();
  }
}
DART

cat > "$work/main.dart" <<'DART'
import 'dart:io';
import 'package:sync_http/sync_http.dart';

void main(List<String> args) {
  final response =
      SyncHttpClient.getUrl(Uri.parse('http://127.0.0.1:${args.single}/'))
          .close();
  if (response.statusCode != HttpStatus.ok) {
    throw StateError('unexpected status ${response.statusCode}');
  }
  if (response.body != 'sync_http works') {
    throw StateError('unexpected body ${response.body}');
  }
  print('sync_http smoke test passed');
}
DART

cd "$work"
"$DART" run server.dart > "$work/port" 2> "$work/server.err" &
server=$!
trap 'kill $server 2>/dev/null || true; rm -rf "$work"' EXIT INT TERM

i=0
while [ ! -s "$work/port" ] && [ "$i" -lt 200 ]; do
    sleep 0.1
    i=$((i + 1))
done
if [ ! -s "$work/port" ]; then
    echo "server did not start" >&2
    cat "$work/server.err" >&2
    exit 1
fi

"$DART" run main.dart "$(head -n 1 "$work/port")"
