// 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";
}
