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

library leap_server;

import 'dart:io';

class Conversation {
  HttpRequest request;
  HttpResponse response;

  static const String CONTENT_TYPE = HttpHeaders.CONTENT_TYPE;

  static const String LEAP_LANDING_PAGE =
      'sdk/lib/_internal/compiler/samples/leap/index.html';

  static String landingPage = LEAP_LANDING_PAGE;

  Conversation(this.request, this.response);

  onClosed(_) {
    if (response.statusCode == HttpStatus.OK) return;
    print('Request for ${request.uri} ${response.statusCode}');
  }

  notFound(path) {
    response.statusCode = HttpStatus.NOT_FOUND;
    response.write(htmlInfo('Not Found',
                            'The file "$path" could not be found.'));
    response.close();
  }

  redirect(String location) {
    response.statusCode = HttpStatus.FOUND;
    response.headers.add(HttpHeaders.LOCATION, location);
    response.close();
  }

  handle() {
    response.done
      ..then(onClosed)
      ..catchError(onError);

    String path = request.uri.path;
    if (path == '/') return redirect('/$landingPage');
    if (path == '/favicon.ico') {
      path = '/sdk/lib/_internal/dartdoc/static/favicon.ico';
    }
    if (path.contains('..') || path.contains('%')) return notFound(path);
    var f = new File("./$path");
    f.exists().then((bool exists) {
      if (!exists) return notFound(path);
      if (path.endsWith('.html')) {
        response.headers.set(CONTENT_TYPE, 'text/html');
      } else if (path.endsWith('.dart')) {
        response.headers.set(CONTENT_TYPE, 'application/dart');
      } else if (path.endsWith('.js')) {
        response.headers.set(CONTENT_TYPE, 'application/javascript');
      } else if (path.endsWith('.ico')) {
        response.headers.set(CONTENT_TYPE, 'image/x-icon');
      } else if (path.endsWith('.appcache')) {
        response.headers.set(CONTENT_TYPE, 'text/cache-manifest');
      }
      f.openRead().pipe(response);
    });
  }

  static onRequest(HttpRequest request) {
    new Conversation(request, request.response).handle();
  }

  static onError(error) {
    if (error is HttpParserException) {
      print('Error: ${error.message}');
    } else {
      print('Error: ${error}');
    }
  }

  String htmlInfo(String title, String text) {
    return """
<!DOCTYPE html>
<html lang='en'>
<head>
<title>$title</title>
</head>
<body>
<h1>$title</h1>
<p>$text</p>
</body>
</html>
""";
  }
}

main() {
  List<String> arguments = new Options().arguments;
  if (arguments.length > 0) {
    Conversation.landingPage = arguments[0];
  }
  var host = '127.0.0.1';
  if (arguments.length > 1) {
    host = arguments[1];
  }
  int port = 0;
  if (arguments.length > 2) {
    port = int.parse(arguments[2]);
  }
  HttpServer.bind(host, port).then((HttpServer server) {
    print('HTTP server started on http://$host:${server.port}/');
    server.listen(Conversation.onRequest, onError: Conversation.onError);
  }).catchError((e) {
    print("HttpServer.bind error: $e");
    exit(1);
  });
}
