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

// @dart = 2.6

// 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];
    var type = InternetAddressType._from(addr[0]);
    if (type == InternetAddressType.unix) {
      return _InternetAddress.fromString(addr[1],
          type: InternetAddressType.unix);
    }
    return _InternetAddress(type, 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];
      var type = InternetAddressType._from(result[0]);
      addresses[i] = _InternetAddress(type, 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";
}
