// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:convert' show jsonDecode, utf8;

import 'dart:isolate' show RawReceivePort;

import 'dart:io';

import 'package:front_end/src/fasta/crash.dart' show defaultServerAddress;

void badRequest(HttpRequest request, int status, String message) {
  request.response.statusCode = status;
  request.response.write('''
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>$message</title>
  </head>
  <body>
    <h1>$message</h1>
  </body>
</html>
''');
  request.response.close().catchError((e, s) {
    print("Request error: $e.");
  });
  print("${request.uri}: $message");
}

Future<void> collectLog(DateTime time, HttpRequest request) async {
  String json = await request.cast<List<int>>().transform(utf8.decoder).join();
  var data;
  try {
    data = jsonDecode(json);
  } on FormatException catch (e) {
    print(e);
    return badRequest(
        request, HttpStatus.badRequest, "Malformed JSON data: ${e.message}.");
  }
  if (data is! Map) {
    return badRequest(
        request, HttpStatus.badRequest, "Malformed JSON data: not a map.");
  }
  if (data["type"] != "crash") {
    return badRequest(request, HttpStatus.badRequest,
        "Malformed JSON data: type should be 'crash'.");
  }
  await request.response.close();
  String year = "${time.year}".padLeft(4, "0");
  String month = "${time.month}".padLeft(2, "0");
  String day = "${time.day}".padLeft(2, "0");
  String us = "${time.microsecondsSinceEpoch}".padLeft(19, '0');
  Uri? uri = Uri.base
      .resolve("crash_logs/${data['client']}/$year-$month-$day/$us.log");
  File file = new File.fromUri(uri);
  await file.parent.create(recursive: true);
  await file.writeAsString(json);
  print("Wrote ${uri.toFilePath()}");

  String type = data["type"];
  String? text = data["uri"];
  uri = text == null ? null : Uri.parse(text);
  int charOffset = data["offset"];
  var error = data["error"];
  text = data["trace"];
  StackTrace? trace = text == null ? null : new StackTrace.fromString(text);
  String client = data["client"];
  print("""
date: ${time}
type: $type
client: $client
uri: $uri
offset: $charOffset
error:
$error
trace:
$trace
""");
}

Future<void> main(List<String> arguments) async {
  RawReceivePort keepAlive = new RawReceivePort();
  Uri uri;
  if (arguments.length == 1) {
    uri = Uri.base.resolve(arguments.single);
  } else if (arguments.length == 0) {
    uri = Uri.parse(defaultServerAddress);
  } else {
    throw "Unexpected arguments: ${arguments.join(' ')}.";
  }
  int port = uri.hasPort ? uri.port : 0;
  var host = uri.host.isEmpty ? InternetAddress.loopbackIPv4 : uri.host;
  HttpServer server = await HttpServer.bind(host, port);
  print("Listening on http://${server.address.host}:${server.port}/");
  await for (HttpRequest request in server) {
    if (request.method != "POST") {
      badRequest(request, HttpStatus.methodNotAllowed, "Not allowed.");
      continue;
    }
    if (request.uri.path != "/") {
      badRequest(request, HttpStatus.notFound, "Not found.");
      continue;
    }
    await collectLog(new DateTime.now(), request);
  }
  keepAlive.close();
}
