// 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.


class _SocketBase extends NativeFieldWrapperClass1 {
  // Bit flags used when communicating between the eventhandler and
  // dart code. The EVENT flags are used to indicate events of
  // interest when sending a message from dart code to the
  // eventhandler. When receiving a message from the eventhandler the
  // EVENT flags indicate the events that actually happened. The
  // COMMAND flags are used to send commands from dart to the
  // eventhandler. COMMAND flags are never received from the
  // eventhandler. Additional flags are used to communicate other
  // information.
  static const int _IN_EVENT = 0;
  static const int _OUT_EVENT = 1;
  static const int _ERROR_EVENT = 2;
  static const int _CLOSE_EVENT = 3;

  static const int _CLOSE_COMMAND = 8;
  static const int _SHUTDOWN_READ_COMMAND = 9;
  static const int _SHUTDOWN_WRITE_COMMAND = 10;

  // Flag send to the eventhandler providing additional information on
  // the type of the file descriptor.
  static const int _LISTENING_SOCKET = 16;
  static const int _PIPE = 17;

  static const int _FIRST_EVENT = _IN_EVENT;
  static const int _LAST_EVENT = _CLOSE_EVENT;

  static const int _FIRST_COMMAND = _CLOSE_COMMAND;
  static const int _LAST_COMMAND = _SHUTDOWN_WRITE_COMMAND;

  _SocketBase () {
    _handlerMap = new List(_LAST_EVENT + 1);
    _handlerMask = 0;
    _canActivateHandlers = true;
    _closed = true;
    _EventHandler._start();
    _hashCode = _nextHashCode;
    _nextHashCode = (_nextHashCode + 1) & 0xFFFFFFF;
  }

  // Multiplexes socket events to the socket handlers.
  void _multiplex(int event_mask) {
    _canActivateHandlers = false;
    for (int i = _FIRST_EVENT; i <= _LAST_EVENT; i++) {
      if (((event_mask & (1 << i)) != 0)) {
        if ((i == _CLOSE_EVENT) && this is _Socket && !_closed) {
          _closedRead = true;
          if (_closedWrite) _close();
        }

        var eventHandler = _handlerMap[i];
        if (eventHandler != null || i == _ERROR_EVENT) {
          // Unregister the out handler before executing it.
          if (i == _OUT_EVENT) _setHandler(i, null);

          // Don't call the in handler if there is no data available
          // after all.
          if ((i == _IN_EVENT) && (this is _Socket) && (available() == 0)) {
            continue;
          }
          if (i == _ERROR_EVENT) {
            _reportError(_getError(), "");
            close();
          } else {
            eventHandler();
          }
        }
      }
    }
    _canActivateHandlers = true;
    _activateHandlers();
  }

  void _setHandler(int event, Function callback) {
    if (callback == null) {
      _handlerMask &= ~(1 << event);
    } else {
      _handlerMask |= (1 << event);
    }
    _handlerMap[event] = callback;
    // If the socket is only for writing then close the receive port
    // when not waiting for any events.
    if (this is _Socket &&
        _closedRead &&
        _handlerMask == 0 &&
        _handler != null) {
      _handler.close();
      _handler = null;
    } else {
      _activateHandlers();
    }
  }

  OSError _getError() native "Socket_GetError";
  int _getPort() native "Socket_GetPort";

  void set onError(void callback(e)) {
    _setHandler(_ERROR_EVENT, callback);
  }

  void _activateHandlers() {
    if (_canActivateHandlers && !_closed) {
      if (_handlerMask == 0) {
        if (_handler != null) {
          _handler.close();
          _handler = null;
        }
        return;
      }
      int data = _handlerMask;
      if (_isListenSocket()) {
        data |= (1 << _LISTENING_SOCKET);
      } else {
        if (_closedRead) { data &= ~(1 << _IN_EVENT); }
        if (_closedWrite) { data &= ~(1 << _OUT_EVENT); }
        if (_isPipe()) data |= (1 << _PIPE);
      }
      _sendToEventHandler(data);
    }
  }

  int get port {
    if (_port === null) {
      _port = _getPort();
    }
    return _port;
  }

  void close([bool halfClose = false]) {
    if (!_closed) {
      if (halfClose) {
        _closeWrite();
      } else {
        _close();
      }
    } else if (_handler != null) {
      // This is to support closing sockets created but never assigned
      // any actual socket.
      _handler.close();
      _handler = null;
    }
  }

  void _closeWrite() {
    if (!_closed) {
      if (_closedRead) {
        _close();
      } else {
        _sendToEventHandler(1 << _SHUTDOWN_WRITE_COMMAND);
      }
      _closedWrite = true;
    }
  }

  void _closeRead() {
    if (!_closed) {
      if (_closedWrite) {
        _close();
      } else {
        _sendToEventHandler(1 << _SHUTDOWN_READ_COMMAND);
      }
      _closedRead = true;
    }
  }

  void _close() {
    if (!_closed) {
      _sendToEventHandler(1 << _CLOSE_COMMAND);
      _handler.close();
      _handler = null;
      _closed = true;
    }
  }

  void _sendToEventHandler(int data) {
    if (_handler === null) {
      _handler = new ReceivePort();
      _handler.receive((var message, ignored) { _multiplex(message); });
    }
    assert(!_closed);
    _EventHandler._sendData(this, _handler, data);
  }

  bool _reportError(error, String message) {
    void doReportError(Exception e) {
      // Invoke the socket error callback if any.
      bool reported = false;
      if (_handlerMap[_ERROR_EVENT] != null) {
        _handlerMap[_ERROR_EVENT](e);
        reported = true;
      }
      // Propagate the error to any additional listeners.
      reported = reported || _propagateError(e);
      if (!reported) throw e;
    }

    // For all errors we close the socket, call the error handler and
    // disable further calls of the error handler.
    close();
    if (error is OSError) {
      doReportError(new SocketIOException(message, error));
    } else if (error is List) {
      assert(_isErrorResponse(error));
      switch (error[0]) {
        case _ILLEGAL_ARGUMENT_RESPONSE:
          doReportError(new ArgumentError());
          break;
        case _OSERROR_RESPONSE:
          doReportError(new SocketIOException(
              message, new OSError(error[2], error[1])));
          break;
        default:
          doReportError(new Exception("Unknown error"));
          break;
      }
    } else {
      doReportError(new SocketIOException(message));
    }
  }

  int hashCode() => _hashCode;

  bool _propagateError(Exception e) => false;

  abstract bool _isListenSocket();
  abstract bool _isPipe();

  // Is this socket closed.
  bool _closed;

  // Dedicated ReceivePort for socket events.
  ReceivePort _handler;

  // Poll event to handler map.
  List _handlerMap;

  // Indicates for which poll events the socket registered handlers.
  int _handlerMask;

  // Indicates if native interrupts can be activated.
  bool _canActivateHandlers;

  // Holds the port of the socket, null if not known.
  int _port;

  // Hash code for the socket. Currently this is just a counter.
  int _hashCode;
  static int _nextHashCode = 0;
  bool _closedRead = false;
  bool _closedWrite = false;
}


class _ServerSocket extends _SocketBase implements ServerSocket {
  // Constructor for server socket. First a socket object is allocated
  // in which the native socket is stored. After that _createBind
  // is called which creates a file descriptor and binds the given address
  // and port to the socket. Null is returned if file descriptor creation or
  // bind failed.
  factory _ServerSocket(String bindAddress, int port, int backlog) {
    _ServerSocket socket = new _ServerSocket._internal();
    var result = socket._createBindListen(bindAddress, port, backlog);
    if (result is OSError) {
      socket.close();
      throw new SocketIOException("Failed to create server socket", result);
    }
    socket._closed = false;
    assert(result);
    if (port != 0) {
      socket._port = port;
    }
    return socket;
  }

  _ServerSocket._internal();

  _accept(Socket socket) native "ServerSocket_Accept";

  _createBindListen(String bindAddress, int port, int backlog)
      native "ServerSocket_CreateBindListen";

  void set onConnection(void callback(Socket connection)) {
    _clientConnectionHandler = callback;
    _setHandler(_SocketBase._IN_EVENT,
                _clientConnectionHandler != null ? _connectionHandler : null);
  }

  void _connectionHandler() {
    if (!_closed) {
      _Socket socket = new _Socket._internal();
      var result = _accept(socket);
      if (result is OSError) {
        _reportError(result, "Accept failed");
      } else if (result) {
        socket._closed = false;
        _clientConnectionHandler(socket);
      } else {
        // Temporary failure accepting the connection. Ignoring
        // temporary failures lets us retry when we wake up with data
        // on the listening socket again.
      }
    }
  }

  bool _isListenSocket() => true;
  bool _isPipe() => false;

  var _clientConnectionHandler;
}


class _Socket extends _SocketBase implements Socket {
  static const HOST_NAME_LOOKUP = 0;

  // Constructs a new socket. During the construction an asynchronous
  // host name lookup is initiated. The returned socket is not yet
  // connected but ready for registration of callbacks.
  factory _Socket(String host, int port) {
    Socket socket = new _Socket._internal();
    _ensureSocketService();
    List request = new List(2);
    request[0] = HOST_NAME_LOOKUP;
    request[1] = host;
    _socketService.call(request).then((response) {
      if (socket._isErrorResponse(response)) {
        socket._reportError(response, "Failed host name lookup");
      } else{
        var result = socket._createConnect(response, port);
        if (result is OSError) {
          socket.close();
          socket._reportError(result, "Connection failed");
        } else {
          socket._closed = false;
          socket._activateHandlers();
        }
      }
    });
    return socket;
  }

  _Socket._internal();
  _Socket._internalReadOnly() : _pipe = true { super._closedWrite = true; }
  _Socket._internalWriteOnly() : _pipe = true { super._closedRead = true; }

  int available() {
    if (!_closed) {
      var result = _available();
      if (result is OSError) {
        _reportError(result, "Available failed");
        return 0;
      } else {
        return result;
      }
    }
    throw new
        SocketIOException("Error: available failed - invalid socket handle");
  }

  _available() native "Socket_Available";

  int readList(List<int> buffer, int offset, int bytes) {
    if (!_closed) {
      if (bytes == 0) {
        return 0;
      }
      if (offset < 0) {
        throw new IndexOutOfRangeException(offset);
      }
      if (bytes < 0) {
        throw new IndexOutOfRangeException(bytes);
      }
      if ((offset + bytes) > buffer.length) {
        throw new IndexOutOfRangeException(offset + bytes);
      }
      var result = _readList(buffer, offset, bytes);
      if (result is OSError) {
        _reportError(result, "Read failed");
        return -1;
      }
      return result;
    }
    throw new
        SocketIOException("Error: readList failed - invalid socket handle");
  }

  _readList(List<int> buffer, int offset, int bytes) native "Socket_ReadList";

  int writeList(List<int> buffer, int offset, int bytes) {
    if (buffer is! List || offset is! int || bytes is! int) {
      throw new ArgumentError(
          "Invalid arguments to writeList on Socket");
    }
    if (!_closed) {
      if (bytes == 0) {
        return 0;
      }
      if (offset < 0) {
        throw new IndexOutOfRangeException(offset);
      }
      if (bytes < 0) {
        throw new IndexOutOfRangeException(bytes);
      }
      if ((offset + bytes) > buffer.length) {
        throw new IndexOutOfRangeException(offset + bytes);
      }
      _BufferAndOffset bufferAndOffset =
          _ensureFastAndSerializableBuffer(buffer, offset, bytes);
      var result =
          _writeList(bufferAndOffset.buffer, bufferAndOffset.offset, bytes);
      if (result is OSError) {
        _reportError(result, "Write failed");
        // If writing fails we return 0 as the number of bytes and
        // report the error on the error handler.
        result = 0;
      }
      return result;
    }
    throw new SocketIOException("writeList failed - invalid socket handle");
  }

  _writeList(List<int> buffer, int offset, int bytes)
      native "Socket_WriteList";

  bool _isErrorResponse(response) {
    return response is List && response[0] != _SUCCESS_RESPONSE;
  }

  bool _createConnect(String host, int port) native "Socket_CreateConnect";

  void set onWrite(void callback()) {
    if (_outputStream != null) throw new StreamException(
            "Cannot set write handler when output stream is used");
    _clientWriteHandler = callback;
    _updateOutHandler();
  }

  void set onConnect(void callback()) {
    if (_seenFirstOutEvent || _outputStream != null) {
      throw new StreamException(
          "Cannot set connect handler when already connected");
    }
    if (_outputStream != null) {
      throw new StreamException(
          "Cannot set connect handler when output stream is used");
    }
    _clientConnectHandler = callback;
    _updateOutHandler();
  }

  void set onData(void callback()) {
    if (_inputStream != null) throw new StreamException(
            "Cannot set data handler when input stream is used");
    _onData = callback;
  }

  void set onClosed(void callback()) {
    if (_inputStream != null) throw new StreamException(
           "Cannot set close handler when input stream is used");
    _onClosed = callback;
  }

  bool _isListenSocket() => false;

  bool _isPipe() => _pipe;

  InputStream get inputStream {
    if (_inputStream == null) {
      if (_handlerMap[_SocketBase._IN_EVENT] !== null ||
          _handlerMap[_SocketBase._CLOSE_EVENT] !== null) {
        throw new StreamException(
            "Cannot get input stream when socket handlers are used");
      }
      _inputStream = new SocketInputStream(this);
    }
    return _inputStream;
  }

  OutputStream get outputStream {
    if (_outputStream == null) {
      if (_handlerMap[_SocketBase._OUT_EVENT] !== null) {
        throw new StreamException(
            "Cannot get input stream when socket handlers are used");
      }
      _outputStream = new SocketOutputStream(this);
    }
    return _outputStream;
  }

  void set _onWrite(void callback()) {
    _setHandler(_SocketBase._OUT_EVENT, callback);
  }

  void set _onData(void callback()) {
    _setHandler(_SocketBase._IN_EVENT, callback);
  }

  void set _onClosed(void callback()) {
    _setHandler(_SocketBase._CLOSE_EVENT, callback);
  }

  bool _propagateError(Exception e) {
    bool reported = false;
    if (_inputStream != null) {
      reported = reported || _inputStream._onSocketError(e);
    }
    if (_outputStream != null) {
      reported = reported || _outputStream._onSocketError(e);
    }
    return reported;
  }

  void _updateOutHandler() {
    void firstWriteHandler() {
      assert(!_seenFirstOutEvent);
      _seenFirstOutEvent = true;

      // From now on the write handler is only the client write
      // handler (connect handler cannot be called again). Change this
      // before calling any handlers as handlers can change the
      // handlers.
      if (_clientWriteHandler === null) _onWrite = _clientWriteHandler;

      // First out event is socket connected event.
      if (_clientConnectHandler !== null) _clientConnectHandler();
      _clientConnectHandler = null;

      // Always (even for the first out event) call the write handler.
      if (_clientWriteHandler !== null) _clientWriteHandler();
    }

    if (_clientConnectHandler === null && _clientWriteHandler === null) {
      _onWrite = null;
    } else {
      if (_seenFirstOutEvent) {
        _onWrite = _clientWriteHandler;
      } else {
        _onWrite = firstWriteHandler;
      }
    }
  }

  int get remotePort {
    if (_remotePort === null) {
      remoteHost;
    }
    return _remotePort;
  }

  String get remoteHost {
    if (_remoteHost === null) {
      List peer = _getRemotePeer();
      _remoteHost = peer[0];
      _remotePort = peer[1];
    }
    return _remoteHost;
  }

  List _getRemotePeer() native "Socket_GetRemotePeer";

  static SendPort _newServicePort() native "Socket_NewServicePort";

  static void _ensureSocketService() {
    if (_socketService == null) {
      _socketService = _Socket._newServicePort();
    }
  }

  bool _seenFirstOutEvent = false;
  bool _pipe = false;
  Function _clientConnectHandler;
  Function _clientWriteHandler;
  SocketInputStream _inputStream;
  SocketOutputStream _outputStream;
  String _remoteHost;
  int _remotePort;
  static SendPort _socketService;
}
