// Copyright 2015 Google. All rights reserved. Use of this source code is
// governed by a BSD-style license that can be found in the LICENSE file.

library wip.multiplex;

import 'dart:async' show Future;
import 'dart:convert' show jsonEncode;
import 'dart:io' show HttpServer, InternetAddress;

import 'package:logging/logging.dart' show Logger;
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as io;
import 'package:shelf_web_socket/shelf_web_socket.dart' as ws;
import 'package:web_socket_channel/web_socket_channel.dart'
    show WebSocketChannel;
import 'package:webkit_inspection_protocol/dom_model.dart' show WipDomModel;
import 'package:webkit_inspection_protocol/forwarder.dart' show WipForwarder;
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'
    show ChromeConnection, ChromeTab, WipConnection;

class Server {
  static final _log = new Logger('Server');

  Future<HttpServer> _server;
  final ChromeConnection chrome;
  final int port;
  final bool modelDom;

  final _connections = <String, Future<WipConnection>>{};
  final _modelDoms = <String, WipDomModel>{};

  Server(this.port, this.chrome, {this.modelDom}) {
    _server = io.serve(_handler, InternetAddress.anyIPv4, port);
  }

  shelf.Handler get _handler => const shelf.Pipeline()
      .addMiddleware(shelf.logRequests(logger: _shelfLogger))
      .addHandler(new shelf.Cascade()
          .add(_webSocket)
          .add(_mainPage)
          .add(_json)
          .add(_forward)
          .handler);

  void _shelfLogger(String msg, bool isError) {
    if (isError) {
      _log.severe(msg);
    } else {
      _log.info(msg);
    }
  }

  Future<shelf.Response> _mainPage(shelf.Request request) async {
    var path = request.url.pathSegments;
    if (path.isEmpty) {
      var resp = await _mainPageHtml();
      _log.info('mainPage: $resp');
      return new shelf.Response.ok(resp,
          headers: {'Content-Type': 'text/html'});
    }
    return new shelf.Response.notFound(null);
  }

  Future<String> _mainPageHtml() async {
    var html = new StringBuffer(r'''<!DOCTYPE html>
<html>
<head>
<title>Chrome Windows</title>
</head>
<body>
<table>
<thead>
<tr><td>Title</td><td>Description</td></tr>
</thead>
<tbody>''');

    for (var tab in await chrome.getTabs()) {
      html
        ..write('<tr><td><a href="/devtools/inspector.html?ws=localhost:')
        ..write(port)
        ..write('/devtools/page/')
        ..write(tab.id)
        ..write('">');
      if (tab.title != null && tab.title.isNotEmpty) {
        html.write(tab.title);
      } else {
        html.write(tab.url);
      }
      html..write('</a></td><td>')..write(tab.description)..write('</td></tr>');
    }
    html.write(r'''</tbody>
</table>
</body>
</html>''');
    return html.toString();
  }

  Future<shelf.Response> _json(shelf.Request request) async {
    var path = request.url.pathSegments;
    if (path.length == 1 && path[0] == 'json') {
      var resp = jsonEncode(await chrome.getTabs(), toEncodable: _jsonEncode);
      _log.info('json: $resp');
      return new shelf.Response.ok(resp,
          headers: {'Content-Type': 'application/json'});
    }
    return new shelf.Response.notFound(null);
  }

  Future<shelf.Response> _forward(shelf.Request request) async {
    _log.info('forwarding: ${request.url}');
    var dtResp = await chrome.getUrl(request.url.path);

    if (dtResp.statusCode == 200) {
      return new shelf.Response.ok(dtResp,
          headers: {'Content-Type': dtResp.headers.contentType.toString()});
    }
    _log.warning(
        'Forwarded ${request.url} returned statusCode: ${dtResp.statusCode}');
    return new shelf.Response.notFound(null);
  }

  Future<shelf.Response> _webSocket(shelf.Request request) async {
    var path = request.url.pathSegments;
    if (path.length != 3 || path[0] != 'devtools' || path[1] != 'page') {
      return new shelf.Response.notFound(null);
    }
    _log.info('connecting to websocket: ${request.url}');

    return ws.webSocketHandler((WebSocketChannel webSocket) async {
      var debugger = await _connections.putIfAbsent(path[2], () async {
        var tab = await chrome.getTab((tab) => tab.id == path[2]);
        return WipConnection.connect(tab.webSocketDebuggerUrl);
      });
      WipDomModel dom;
      if (modelDom) {
        dom = await _modelDoms.putIfAbsent(path[2], () {
          return new WipDomModel(debugger.dom);
        });
      }
      var forwarder = new WipForwarder(debugger, webSocket.stream.cast(),
          sink: webSocket.sink, domModel: dom);
      debugger.onClose.listen((_) {
        _connections.remove(path[2]);
        _modelDoms.remove(path[2]);
        forwarder.stop();
      });
    })(request);
  }

  Future close() async {
    if (_server != null) {
      await (await _server).close(force: true);
      _server = null;
    }
  }

  _jsonEncode(obj) {
    if (obj is ChromeTab) {
      var json = <String, dynamic>{
        'description': obj.description,
        'devtoolsFrontendUrl': '/devtools/inspector.html'
            '?ws=localhost:$port/devtools/page/${obj.id}',
        'id': obj.id,
        'title': obj.title,
        'type': obj.type,
        'url': obj.url,
        'webSocketDebuggerUrl': 'ws://localhost:$port/devtools/page/${obj.id}'
      };
      if (obj.faviconUrl != null) {
        json['faviconUrl'] = obj.faviconUrl;
      }
      return json;
    } else if (obj is Uri) {
      return obj.toString();
    } else if (obj is Iterable) {
      return obj.toList();
    } else {
      return obj;
    }
  }
}
