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

// part of "common_patch.dart";

@patch
class RawSynchronousSocket {
  @patch
  static RawSynchronousSocket connectSync(host, int port) {
    return _RawSynchronousSocket.connectSync(host, port);
  }
}

class _RawSynchronousSocket implements RawSynchronousSocket {
  final _NativeSynchronousSocket _socket;

  _RawSynchronousSocket(this._socket);

  static RawSynchronousSocket connectSync(host, int port) {
    _throwOnBadPort(port);
    return new _RawSynchronousSocket(
        _NativeSynchronousSocket.connectSync(host, port));
  }

  InternetAddress get address => _socket.address;
  int get port => _socket.port;
  InternetAddress get remoteAddress => _socket.remoteAddress;
  int get remotePort => _socket.remotePort;

  int available() => _socket.available;

  void closeSync() => _socket.closeSync();

  int readIntoSync(List<int> buffer, [int start = 0, int end]) =>
      _socket.readIntoSync(buffer, start, end);

  List<int> readSync(int bytes) => _socket.readSync(bytes);

  void shutdown(SocketDirection direction) => _socket.shutdown(direction);

  void writeFromSync(List<int> buffer, [int start = 0, int end]) =>
      _socket.writeFromSync(buffer, start, end);
}

// The NativeFieldWrapperClass1 can not be used with a mixin, due to missing
// implicit constructor.
class _NativeSynchronousSocketNativeWrapper extends NativeFieldWrapperClass1 {}

// The _NativeSynchronousSocket class encapsulates a synchronous OS socket.
class _NativeSynchronousSocket extends _NativeSynchronousSocketNativeWrapper {
  // Socket close state.
  bool isClosed = false;
  bool isClosedRead = false;
  bool isClosedWrite = false;

  // Holds the address used to connect the socket.
  InternetAddress localAddress;

  // Holds the port of the socket, 0 if not known.
  int localPort = 0;

  _ReadWriteResourceInfo resourceInfo;

  static _NativeSynchronousSocket connectSync(host, int port) {
    if (host == null) {
      throw new ArgumentError("Parameter host cannot be null");
    }
    List<_InternetAddress> addresses = null;
    var error = null;
    if (host is _InternetAddress) {
      addresses = [host];
    } else {
      try {
        addresses = lookup(host);
      } catch (e) {
        error = e;
      }
      if (error != null || addresses == null || addresses.isEmpty) {
        throw createError(error, "Failed host lookup: '$host'");
      }
    }
    assert(addresses is List);
    var it = addresses.iterator;
    _NativeSynchronousSocket connectNext() {
      if (!it.moveNext()) {
        // Could not connect. Throw the first connection error we encountered.
        assert(error != null);
        throw error;
      }
      var address = it.current;
      var socket = new _NativeSynchronousSocket();
      socket.localAddress = address;
      var result = socket._nativeCreateConnectSync(address._in_addr, port);
      if (result is OSError) {
        // Keep first error, if present.
        if (error == null) {
          error = createError(result, "Connection failed", address, port);
        }
        return connectNext();
      } else {
        // Query the local port, for error messages.
        try {
          socket.port;
        } catch (e) {
          if (error == null) {
            error = createError(e, "Connection failed", address, port);
          }
          return connectNext();
        }
        setupResourceInfo(socket);
      }
      return socket;
    }

    return connectNext();
  }

  InternetAddress get address => localAddress;
  int get available => _nativeAvailable();

  int get port {
    if (localPort != 0) {
      return localPort;
    }
    if (isClosed) {
      throw const SocketException.closed();
    }
    var result = _nativeGetPort();
    if (result is OSError) {
      throw result;
    }
    return localPort = result;
  }

  InternetAddress get remoteAddress {
    if (isClosed) {
      throw const SocketException.closed();
    }
    var result = _nativeGetRemotePeer();
    if (result is OSError) {
      throw result;
    }
    var addr = result[0];
    return new _InternetAddress(addr[1], null, addr[2]);
  }

  int get remotePort {
    if (isClosed) {
      throw const SocketException.closed();
    }
    var result = _nativeGetRemotePeer();
    if (result is OSError) {
      throw result;
    }
    return result[1];
  }

  void closeSync() {
    if (!isClosed) {
      _nativeCloseSync();
      _SocketResourceInfo.SocketClosed(resourceInfo);
      isClosed = true;
    }
  }

  // Create the appropriate error/exception from different returned
  // error objects.
  static createError(error, String message,
      [InternetAddress address, int port]) {
    if (error is OSError) {
      return new SocketException(message,
          osError: error, address: address, port: port);
    } else {
      return new SocketException(message, address: address, port: port);
    }
  }

  static List<_InternetAddress> lookup(String host,
      {InternetAddressType type: InternetAddressType.ANY}) {
    var response = _nativeLookupRequest(host, type._value);
    if (response is OSError) {
      throw response;
    }
    List<_InternetAddress> addresses =
        new List<_InternetAddress>(response.length);
    for (int i = 0; i < response.length; ++i) {
      var result = response[i];
      addresses[i] = new _InternetAddress(result[1], host, result[2]);
    }
    return addresses;
  }

  int readIntoSync(List<int> buffer, int start, int end) {
    _checkAvailable();
    if (isClosedRead) {
      throw new SocketException("Socket is closed for reading");
    }

    if ((buffer is! List) ||
        ((start != null) && (start is! int)) ||
        ((end != null) && (end is! int))) {
      throw new ArgumentError("Invalid arguments to readIntoSync");
    }
    if (start == null) {
      throw new ArgumentError("start cannot be null");
    }
    end = RangeError.checkValidRange(start, end, buffer.length);
    if (end == start) {
      return 0;
    }
    var result = _nativeReadInto(buffer, start, (end - start));
    if (result is OSError) {
      throw new SocketException("readIntoSync failed", osError: result);
    }
    resourceInfo.addRead(result);
    return result;
  }

  List<int> readSync(int len) {
    _checkAvailable();
    if (isClosedRead) {
      throw new SocketException("Socket is closed for reading");
    }

    if ((len != null) && (len < 0)) {
      throw new ArgumentError("Illegal length $len");
    }
    if (len == 0) {
      return null;
    }
    var result = _nativeRead(len);
    if (result is OSError) {
      throw result;
    }
    assert(resourceInfo != null);
    if (result != null) {
      if (resourceInfo != null) {
        resourceInfo.totalRead += result.length;
      }
    }
    if (resourceInfo != null) {
      resourceInfo.didRead();
    }
    return result;
  }

  static void setupResourceInfo(_NativeSynchronousSocket socket) {
    socket.resourceInfo = new _SocketResourceInfo(socket);
  }

  void shutdown(SocketDirection direction) {
    if (isClosed) {
      return;
    }
    switch (direction) {
      case SocketDirection.receive:
        shutdownRead();
        break;
      case SocketDirection.send:
        shutdownWrite();
        break;
      case SocketDirection.both:
        closeSync();
        break;
      default:
        throw new ArgumentError(direction);
    }
  }

  void shutdownRead() {
    if (isClosed || isClosedRead) {
      return;
    }
    if (isClosedWrite) {
      closeSync();
    } else {
      _nativeShutdownRead();
    }
    isClosedRead = true;
  }

  void shutdownWrite() {
    if (isClosed || isClosedWrite) {
      return;
    }
    if (isClosedRead) {
      closeSync();
    } else {
      _nativeShutdownWrite();
    }
    isClosedWrite = true;
  }

  void writeFromSync(List<int> buffer, int start, int end) {
    _checkAvailable();
    if (isClosedWrite) {
      throw new SocketException("Socket is closed for writing");
    }
    if ((buffer is! List) ||
        ((start != null) && (start is! int)) ||
        ((end != null) && (end is! int))) {
      throw new ArgumentError("Invalid arguments to writeFromSync");
    }
    if (start == null) {
      throw new ArgumentError("start cannot be equal to null");
    }

    end = RangeError.checkValidRange(start, end, buffer.length);
    if (end == start) {
      return;
    }

    _BufferAndStart bufferAndStart =
        _ensureFastAndSerializableByteData(buffer, start, end);
    var result = _nativeWrite(bufferAndStart.buffer, bufferAndStart.start,
        end - (start - bufferAndStart.start));
    if (result is OSError) {
      throw new SocketException("writeFromSync failed", osError: result);
    }
    assert(resourceInfo != null);
    if (resourceInfo != null) {
      resourceInfo.addWrite(result);
    }
  }

  void _checkAvailable() {
    if (isClosed) {
      throw const SocketException.closed();
    }
  }

  // Native method declarations.
  static _nativeLookupRequest(host, int type)
      native "SynchronousSocket_LookupRequest";
  _nativeCreateConnectSync(host, int port)
      native "SynchronousSocket_CreateConnectSync";
  _nativeAvailable() native "SynchronousSocket_Available";
  _nativeCloseSync() native "SynchronousSocket_CloseSync";
  int _nativeGetPort() native "SynchronousSocket_GetPort";
  List _nativeGetRemotePeer() native "SynchronousSocket_GetRemotePeer";
  _nativeRead(int len) native "SynchronousSocket_Read";
  _nativeReadInto(List<int> buffer, int offset, int bytes)
      native "SynchronousSocket_ReadList";
  _nativeShutdownRead() native "SynchronousSocket_ShutdownRead";
  _nativeShutdownWrite() native "SynchronousSocket_ShutdownWrite";
  _nativeWrite(List<int> buffer, int offset, int bytes)
      native "SynchronousSocket_WriteList";
}
