#!mojo mojo:dart_content_handler
// Copyright 2014 The Chromium Authors. 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:async';
import 'dart:core';
import 'dart:typed_data';

import 'package:mojo/application.dart';
import 'package:mojo/bindings.dart';
import 'package:mojo/core.dart';
import 'package:mojo/mojo/network_error.mojom.dart';
import 'package:mojo_services/mojo/files/file.mojom.dart' as files;
import 'package:mojo_services/mojo/files/types.mojom.dart' as files;
import 'package:mojo_services/mojo/net_address.mojom.dart';
import 'package:mojo_services/mojo/network_service.mojom.dart';
import 'package:mojo_services/mojo/tcp_bound_socket.mojom.dart';
import 'package:mojo_services/mojo/tcp_connected_socket.mojom.dart';
import 'package:mojo_services/mojo/terminal/terminal_client.mojom.dart';

void ignoreFuture(Future f) {
  f.catchError((e) {});
}

NetAddress makeIPv4NetAddress(List<int> addr, int port) {
  var rv = new NetAddress();
  rv.family = NetAddressFamily.ipv4;
  rv.ipv4 = new NetAddressIPv4();
  rv.ipv4.addr = new List<int>.from(addr);
  rv.ipv4.port = port;
  return rv;
}

void fputs(files.File f, String s) {
  ignoreFuture(f.write((s + '\n').codeUnits, 0, files.Whence.fromCurrent));
}

// Connects the terminal |File| and the socket.
// TODO(vtl):
// * Error handling: both connection/socket errors and terminal errors.
// * Relatedly, we should listen for _socketSender's peer being closed (also
//   _socket, I guess).
// * Handle the socket send pipe being full (currently, we assume it's never
//   full).
class Connector {
  final Application _application;
  files.FileProxy _terminal;
  TcpConnectedSocketProxy _socket;
  MojoDataPipeProducer _socketSender;
  MojoDataPipeConsumer _socketReceiver;
  MojoEventSubscription _socketReceiverEventSubscription;
  final ByteData _readBuffer;
  final ByteData _writeBuffer;

  // TODO(vtl): Don't just hard-code buffer sizes.
  Connector(this._application, this._terminal)
      : _readBuffer = new ByteData(16 * 1024),
        _writeBuffer = new ByteData(16 * 1024);

  Future connect(NetAddress remote_address) async {
    try {
      var networkService = new NetworkServiceProxy.unbound();
      _application.connectToService('mojo:network_service', networkService);

      NetAddress local_address = makeIPv4NetAddress([0, 0, 0, 0], 0);
      var boundSocket = new TcpBoundSocketProxy.unbound();
      await networkService.ptr.createTcpBoundSocket(local_address, boundSocket);
      await networkService.close();

      var sendDataPipe = new MojoDataPipe();
      _socketSender = sendDataPipe.producer;
      var receiveDataPipe = new MojoDataPipe();
      _socketReceiver = receiveDataPipe.consumer;
      _socket = new TcpConnectedSocketProxy.unbound();
      await boundSocket.ptr.connect(remote_address, sendDataPipe.consumer,
          receiveDataPipe.producer, _socket);
      await boundSocket.close();

      // Set up reading from the terminal.
      _startReadingFromTerminal();

      // Set up reading from the socket.
      _socketReceiverEventSubscription =
          new MojoEventSubscription(_socketReceiver.handle);
      _socketReceiverEventSubscription.subscribe(_onSocketReceiverEvent);
    } catch (e) {
      _shutDown();
    }
  }

  void _startReadingFromTerminal() {
    // TODO(vtl): Do we have to do something on error?
    _terminal.ptr
        .read(_writeBuffer.lengthInBytes, 0, files.Whence.fromCurrent)
        .then(_onReadFromTerminal)
        .catchError((e) {
      _shutDown();
    });
  }

  void _onReadFromTerminal(files.FileReadResponseParams p) {
    if (p.error != files.Error.ok) {
      // TODO(vtl): Do terminal errors.
      return;
    }

    // TODO(vtl): Verify that |bytesRead.length| is within the expected range.
    for (var i = 0, j = 0; i < p.bytesRead.length; i++, j++) {
      // TODO(vtl): Temporary hack: Translate \r to \n, since we don't have
      // built-in support for that.
      if (p.bytesRead[i] == 13) {
        _writeBuffer.setUint8(i, 10);
      } else {
        _writeBuffer.setUint8(i, p.bytesRead[i]);
      }
    }

    // TODO(vtl): Handle the send data pipe being full (or closed).
    _socketSender
        .write(new ByteData.view(_writeBuffer.buffer, 0, p.bytesRead.length));

    _startReadingFromTerminal();
  }

  void _onSocketReceiverEvent(int mojoSignals) {
    var shouldShutDown = false;
    if (MojoHandleSignals.isReadable(mojoSignals)) {
      var numBytesRead = _socketReceiver.read(_readBuffer);
      if (_socketReceiver.status == MojoResult.kOk) {
        assert(numBytesRead > 0);
        _terminal.ptr
            .write(_readBuffer.buffer.asUint8List(0, numBytesRead), 0,
                files.Whence.fromCurrent)
            .catchError((e) {
          _shutDown();
        });
        _socketReceiverEventSubscription.enableReadEvents();
      } else {
        shouldShutDown = true;
      }
    } else if (MojoHandleSignals.isPeerClosed(mojoSignals)) {
      shouldShutDown = true;
    } else {
      String signals = MojoHandleSignals.string(mojoSignals);
      throw 'Unexpected handle event: $signals';
    }
    if (shouldShutDown) {
      _shutDown();
    }
  }

  void _shutDown() {
    if (_socketReceiverEventSubscription != null) {
      ignoreFuture(_socketReceiverEventSubscription.close());
      _socketReceiverEventSubscription = null;
    }
    if (_socketSender != null) {
      if (_socketSender.handle.isValid) _socketSender.handle.close();
      _socketSender = null;
    }
    if (_socketReceiver != null) {
      if (_socketReceiver.handle.isValid) _socketReceiver.handle.close();
      _socketReceiver = null;
    }
    if (_terminal != null) {
      ignoreFuture(_terminal.close());
      _terminal = null;
    }
  }
}

class TerminalClientImpl implements TerminalClient {
  TerminalClientStub _stub;
  Application _application;
  String _resolvedUrl;

  TerminalClientImpl(
      this._application, this._resolvedUrl, MojoMessagePipeEndpoint endpoint) {
    _stub = new TerminalClientStub.fromEndpoint(endpoint, this);
  }

  @override
  void connectToTerminal(files.FileProxy terminal) {
    var url = Uri.parse(_resolvedUrl);
    NetAddress remote_address;
    try {
      remote_address = _getNetAddressFromUrl(url);
    } catch (e) {
      fputs(
          terminal.ptr,
          'HALP: Add a query: ?host=<host>&port=<port>\n'
              '(<host> must be "localhost" or n1.n2.n3.n4)\n\n'
              'Got query parameters:\n' +
              url.queryParameters.toString());
      ignoreFuture(terminal.close());
      return;
    }

    // TODO(vtl): Currently, we only do IPv4, so this should work.
    fputs(
        terminal.ptr,
        'Connecting to: ' +
            remote_address.ipv4.addr.join('.') +
            ':' +
            remote_address.ipv4.port.toString() +
            '...');

    var connector = new Connector(_application, terminal);
    // TODO(vtl): Do we have to do something on error?
    connector.connect(remote_address).catchError((e) {});
  }

  // Note: May throw all sorts of things.
  static NetAddress _getNetAddressFromUrl(Uri url) {
    var params = url.queryParameters;
    var host = params['host'];
    return makeIPv4NetAddress(
        (host == 'localhost') ? [127, 0, 0, 1] : Uri.parseIPv4Address(host),
        int.parse(params['port']));
  }
}

class NetcatApplication extends Application {
  NetcatApplication.fromHandle(MojoHandle handle) : super.fromHandle(handle);

  @override
  void acceptConnection(String requestorUrl, String resolvedUrl,
      ApplicationConnection connection) {
    connection.provideService(TerminalClient.serviceName,
        (endpoint) => new TerminalClientImpl(this, resolvedUrl, endpoint));
  }
}

main(List args, Object handleToken) {
  MojoHandle appHandle = new MojoHandle(handleToken);
  new NetcatApplication.fromHandle(appHandle)
    ..onError = ((Object e) {
      MojoHandle.reportLeakedHandles();
    });
}
