// 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 dart.io;

/// A low-level class for communicating synchronously over a TCP socket.
///
/// Warning: [RawSynchronousSocket] should probably only be used to connect to
/// 'localhost'. The operations below will block the calling thread to wait for
/// a response from the network. The thread can process no other events while
/// waiting for these operations to complete. [RawSynchronousSocket] is not
/// suitable for applications that require high performance or asynchronous I/O
/// such as a server. Instead such applications should use the non-blocking
/// sockets and asynchronous operations in the [Socket] or [RawSocket] classes.
abstract class RawSynchronousSocket {
  /// Creates a new socket connection and returns a [RawSynchronousSocket].
  ///
  /// The [host] can either be a [String] or an [InternetAddress].
  /// If [host] is a [String], [connectSync] will perform a
  /// [InternetAddress.lookup] and try all returned [InternetAddress]es,
  /// until connected.
  /// Unless a connection was established,
  /// the error from the first failing connection is returned.
  external static RawSynchronousSocket connectSync(host, int port);

  /// The number of received and unread bytes in the socket that can be read.
  int available();

  /// Closes the [RawSynchronousSocket].
  ///
  /// Once [closeSync] has been called, attempting to call [readSync],
  /// [readIntoSync], [writeFromSync], [remoteAddress], and [remotePort] will
  /// cause a [SocketException] to be thrown.
  void closeSync();

  /// Reads bytes into an existing [buffer].
  ///
  /// Reads bytes and writes then into the range of [buffer]
  /// from [start] to [end].
  /// The [start] must be non-negative and no greater than [buffer].length.
  /// If [end] is omitted, it defaults to [buffer].length.
  /// Otherwise [end] must be no less than [start]
  /// and no greater than [buffer].length.
  ///
  /// Returns the number of bytes read. This maybe be less than `end - start`
  /// if the file doesn't have that many bytes to read.
  int readIntoSync(List<int> buffer, [int start = 0, int? end]);

  /// Reads up to [bytes] bytes from the socket.
  ///
  /// Blocks and waits for a response of up to a specified number of bytes
  /// sent by the socket. [bytes] specifies the maximum number of bytes to
  /// be read. Returns the list of bytes read, which could be less than the
  /// value specified by [bytes].
  List<int>? readSync(int bytes);

  /// Shuts down a socket in the provided direction.
  ///
  /// Calling shutdown will never throw an exception and calling it several times
  /// is supported. If both [SocketDirection.RECEIVE] and [SocketDirection.SEND]
  /// directions are closed, the socket is closed completely, the same as if
  /// [closeSync] has been called.
  void shutdown(SocketDirection direction);

  /// Writes from a [buffer] to the socket.
  ///
  /// Will read the buffer from index [start] to index [end].
  /// The [start] must be non-negative and no greater than [buffer].length.
  /// If [end] is omitted, it defaults to [buffer].length.
  /// Otherwise [end] must be no less than [start]
  /// and no greater than [buffer].length.
  void writeFromSync(List<int> buffer, [int start = 0, int? end]);

  /// The port used by this socket.
  int get port;

  /// The remote port connected to by this socket.
  int get remotePort;

  /// The [InternetAddress] used to connect this socket.
  InternetAddress get address;

  /// The remote [InternetAddress] connected to by this socket.
  InternetAddress get remoteAddress;
}
