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