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

#ifndef RUNTIME_BIN_SOCKET_H_
#define RUNTIME_BIN_SOCKET_H_

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/file.h"
#include "bin/reference_counting.h"
#include "bin/socket_base.h"
#include "bin/thread.h"
#include "bin/utils.h"
#include "platform/hashmap.h"

namespace dart {
namespace bin {

// TODO(bkonyi): Socket should also inherit from SocketBase once it is
// refactored to use instance methods when possible.

// We write Sockets into the native field of the _NativeSocket object
// on the Dart side. They are allocated in SetSocketIdNativeField(), and are
// deallocated either from the finalizer attached to _NativeSockets there, or
// from the eventhandler, whichever drops the last reference.
class Socket : public ReferenceCounted<Socket> {
 public:
  enum SocketRequest {
    kLookupRequest = 0,
    kListInterfacesRequest = 1,
    kReverseLookupRequest = 2,
  };

  enum SocketFinalizer {
    kFinalizerNormal,
    kFinalizerListening,
    kFinalizerStdio,
    kFinalizerSignal,
  };

  // Keep in sync with constants in _NativeSocket in socket_patch.dart.
  enum SocketType {
    kTcpSocket = 18,
    kUdpSocket = 19,
    kInternalSocket = 20,
    kInternalSignalSocket = 21,
  };

  explicit Socket(intptr_t fd);

  intptr_t fd() const { return fd_; }

  // Close fd and may need to decrement the count of handle by calling
  // release().
  void CloseFd();
  // Set fd_ to closed. On fuchsia and win, shared socket should not
  // release handle but only SetClosedFd().
  void SetClosedFd();

  Dart_Port isolate_port() const { return isolate_port_; }

  Dart_Port port() const { return port_; }
  void set_port(Dart_Port port) { port_ = port; }

  uint8_t* udp_receive_buffer() const { return udp_receive_buffer_; }
  void set_udp_receive_buffer(uint8_t* buffer) { udp_receive_buffer_ = buffer; }

  static bool Initialize();

  // Creates a socket which is bound and connected. The port to connect to is
  // specified as the port component of the passed RawAddr structure.
  static intptr_t CreateConnect(const RawAddr& addr);
  static intptr_t CreateUnixDomainConnect(const RawAddr& addr);
  // Creates a socket which is bound and connected. The port to connect to is
  // specified as the port component of the passed RawAddr structure.
  static intptr_t CreateBindConnect(const RawAddr& addr,
                                    const RawAddr& source_addr);
  static intptr_t CreateUnixDomainBindConnect(const RawAddr& addr,
                                              const RawAddr& source_addr);
  // Creates a datagram socket which is bound. The port to bind
  // to is specified as the port component of the RawAddr structure.
  static intptr_t CreateBindDatagram(const RawAddr& addr,
                                     bool reuseAddress,
                                     bool reusePort,
                                     int ttl = 1);

  static CObject* LookupRequest(const CObjectArray& request);
  static CObject* ListInterfacesRequest(const CObjectArray& request);
  static CObject* ReverseLookupRequest(const CObjectArray& request);

  static Dart_Port GetServicePort();

  static void SetSocketIdNativeField(Dart_Handle handle,
                                     intptr_t id,
                                     SocketFinalizer finalizer);
  static void ReuseSocketIdNativeField(Dart_Handle handle,
                                       Socket* socket,
                                       SocketFinalizer finalizer);
  static Socket* GetSocketIdNativeField(Dart_Handle socket);

  static bool short_socket_read() { return short_socket_read_; }
  static void set_short_socket_read(bool short_socket_read) {
    short_socket_read_ = short_socket_read;
  }
  static bool short_socket_write() { return short_socket_write_; }
  static void set_short_socket_write(bool short_socket_write) {
    short_socket_write_ = short_socket_write;
  }

  static bool IsSignalSocketFlag(intptr_t flag) {
    return ((flag & (0x1 << kInternalSignalSocket)) != 0);
  }

 private:
  ~Socket() {
    ASSERT(fd_ == kClosedFd);
    free(udp_receive_buffer_);
    udp_receive_buffer_ = nullptr;
  }

  static constexpr int kClosedFd = -1;

  static bool short_socket_read_;
  static bool short_socket_write_;

  intptr_t fd_;
  Dart_Port isolate_port_;
  Dart_Port port_;
  uint8_t* udp_receive_buffer_;

  friend class ReferenceCounted<Socket>;
  DISALLOW_COPY_AND_ASSIGN(Socket);
};

class ServerSocket {
 public:
  static constexpr intptr_t kTemporaryFailure = -2;

  static intptr_t Accept(intptr_t fd);

  // Creates a socket which is bound and listens. The port to listen on is
  // specified in the port component of the passed RawAddr structure.
  //
  // Returns a positive integer if the call is successful. In case of failure
  // it returns:
  //
  //   -1: system error (errno set)
  //   -5: invalid bindAddress
  static intptr_t CreateBindListen(const RawAddr& addr,
                                   intptr_t backlog,
                                   bool v6_only = false);
  static intptr_t CreateUnixDomainBindListen(const RawAddr& addr,
                                             intptr_t backlog);

  // Start accepting on a newly created listening socket. If it was unable to
  // start accepting incoming sockets, the fd is invalidated.
  static bool StartAccept(intptr_t fd);

 private:
  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket);
};

class ListeningSocketRegistry {
 public:
  ListeningSocketRegistry()
      : sockets_by_port_(SameIntptrValue, kInitialSocketsCount),
        sockets_by_fd_(SameIntptrValue, kInitialSocketsCount),
        unix_domain_sockets_(nullptr),
        mutex_() {}

  ~ListeningSocketRegistry() { CloseAllSafe(); }

  static void Initialize();

  static ListeningSocketRegistry* Instance();

  static void Cleanup();

  // Bind `socket_object` to `addr`.
  // Return Dart_True() if succeed.
  // This function should be called from a dart runtime call in order to create
  // a new (potentially shared) socket.
  Dart_Handle CreateBindListen(Dart_Handle socket_object,
                               const RawAddr& addr,
                               intptr_t backlog,
                               bool v6_only,
                               bool shared);
  // Bind unix domain socket`socket_object` to `path`.
  // Return Dart_True() if succeed.
  // This function should be called from a dart runtime call in order to create
  // a new socket.
  Dart_Handle CreateUnixDomainBindListen(Dart_Handle socket_object,
                                         Namespace* namespc,
                                         const char* path,
                                         intptr_t backlog,
                                         bool shared);

  // This should be called from the event handler for every kCloseEvent it gets
  // on listening sockets.
  //
  // Returns `true` if the last reference has been dropped and the underlying
  // socket can be closed.
  //
  // The caller is responsible for obtaining the mutex first, before calling
  // this function.
  bool CloseSafe(Socket* socketfd);

  Mutex* mutex() { return &mutex_; }

 private:
  struct OSSocket {
    RawAddr address;
    int port;
    bool v6_only;
    bool shared;
    int ref_count;
    intptr_t fd;

    // Only applicable to Unix domain socket, where address.addr.sa_family
    // == AF_UNIX.
    Namespace* namespc;

    // Singly linked lists of OSSocket instances which listen on the same port
    // but on different addresses.
    OSSocket* next;

    OSSocket(const RawAddr& address,
             int port,
             bool v6_only,
             bool shared,
             Socket* socketfd,
             Namespace* namespc)
        : address(address),
          port(port),
          v6_only(v6_only),
          shared(shared),
          ref_count(0),
          namespc(namespc),
          next(nullptr) {
      fd = socketfd->fd();
    }
  };

  static constexpr intptr_t kInitialSocketsCount = 8;

  OSSocket* FindOSSocketWithAddress(OSSocket* current, const RawAddr& addr) {
    while (current != nullptr) {
      if (SocketAddress::AreAddressesEqual(current->address, addr)) {
        return current;
      }
      current = current->next;
    }
    return nullptr;
  }

  OSSocket* FindMatchingUnixDomainSocket(OSSocket* current,
                                         Namespace* namespc,
                                         const RawAddr& addr) {
    if (addr.is_abstract_unix_socket()) {
      return FindOSSocketWithAddress(current, addr);
    }

    while (current != nullptr) {
      ASSERT(current->address.addr.sa_family == AF_UNIX);
      if (current->address.is_abstract_unix_socket()) {
        continue;
      }

      if (File::AreIdentical(current->namespc, current->address.un.sun_path,
                             namespc, addr.un.sun_path) == File::kIdentical) {
        return current;
      }

      current = current->next;
    }
    return nullptr;
  }

  static bool SameIntptrValue(void* key1, void* key2) {
    return reinterpret_cast<intptr_t>(key1) == reinterpret_cast<intptr_t>(key2);
  }

  static uint32_t GetHashmapHashFromIntptr(intptr_t i) {
    return static_cast<uint32_t>((i + 1) & 0xFFFFFFFF);
  }

  static void* GetHashmapKeyFromIntptr(intptr_t i) {
    return reinterpret_cast<void*>(i + 1);
  }

  OSSocket* LookupByPort(intptr_t port);
  void InsertByPort(intptr_t port, OSSocket* socket);
  void RemoveByPort(intptr_t port);

  OSSocket* LookupByFd(Socket* fd);
  void InsertByFd(Socket* fd, OSSocket* socket);
  void RemoveByFd(Socket* fd);

  bool CloseOneSafe(OSSocket* os_socket, Socket* socket);
  void CloseAllSafe();

  SimpleHashMap sockets_by_port_;
  SimpleHashMap sockets_by_fd_;

  OSSocket* unix_domain_sockets_;

  Mutex mutex_;

  DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry);
};

}  // namespace bin
}  // namespace dart

#endif  // RUNTIME_BIN_SOCKET_H_
