// Copyright (c) 2019, 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.

/// Serves the log over HTTP for a failing test on a given runner and build

import 'dart:async';
import 'dart:io';

import 'package:dart_ci/src/approvals_feed.dart';
import 'package:dart_ci/src/get_log.dart';

void main() async {
  await refresh();
  final server = await HttpServer.bind(InternetAddress.anyIPv4, 8080);
  server.listen(dispatchingServer);
  print("Server started at ip:port ${server.address}:${server.port}");
  Timer.periodic(Duration(minutes: 10), (timer) async {
    try {
      await refresh();
    } catch (e, t) {
      print(e);
      print(t);
    }
  });
}

Future<void> refresh() async {
  await getApprovals();
}

Future<void> dispatchingServer(HttpRequest request) async {
  try {
    if (request.uri.path == '/') {
      return await serveFrontPage(request);
    } else if (request.uri.path.startsWith('/log/')) {
      return await serveLog(request);
    } else if (request.uri.path.startsWith('/changes')) {
      return await serveChanges(request);
    } else if (request.uri.path.startsWith('/approvals/')) {
      return await serveApprovals(request);
    } else {
      return await notFound(request);
    }
  } catch (e, t) {
    print(e);
    print(t);
    serverError(request);
  }
}

void serveFrontPage(HttpRequest request) async {
  request.response.headers.contentType = ContentType.html;
  request.response.write("""<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Dart Continuous Integration</title>
  </head>
  <body>
    <h1>Dart Continuous Integration</h1>
    <h2><a href="https://dart-ci.firebaseapp.com/#showAllCommits=false&showLatestFailures=true">Results Feed</a></h2>
    <h2><a href="approvals/">Approvals Feed</a></h2>
  </body>
</html>
""");
  request.response.close();
}

Future<void> serveLog(HttpRequest request) async {
  final parts = request.uri.pathSegments;
  final builder = parts[1];
  final configuration = parts[2];
  final build = parts[3];
  final test = parts.skip(4).join('/');

  if (build == 'latest') {
    final actualBuild = await getLatestBuildNumber(builder);
    return redirectTemporary(
        request, '/log/$builder/$configuration/$actualBuild/$test');
  }
  final log = await getLog(builder, build, configuration, test);
  if (log == null) {
    return noLog(request, builder, build, test);
  }
  final response = request.response;
  response.headers.contentType = ContentType.text;
  response.headers.expires = DateTime.now().add(const Duration(days: 30));
  response.write(log);
  return response.close();
}

Future<void> redirectTemporary(HttpRequest request, String newPath) {
  request.response.headers.add(HttpHeaders.locationHeader, newPath);
  request.response.statusCode = HttpStatus.movedTemporarily;
  return request.response.close();
}

Future<void> serveChanges(HttpRequest request) async {
  return request.response.redirect(Uri.parse(
      'https://dart-ci.firebaseapp.com/#showAllCommits=false&showLatestFailures=true'),
      status: HttpStatus.movedPermanently);
}

Future<void> notFound(HttpRequest request) {
  request.response.statusCode = HttpStatus.notFound;
  return request.response.close();
}

Future<void> noLog(
    HttpRequest request, String builder, String build, String test) async {
  request.response.headers.contentType = ContentType.text;
  request.response
      .write("No log for test $test on build $build of builder $builder");
  return request.response.close();
}

Future<void> serverError(HttpRequest request) {
  try {
    request.response.statusCode = HttpStatus.internalServerError;
  } catch (e) {
    print(e);
  }
  return request.response.close();
}
