// 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,
                               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(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* FindOSSocketWithPath(OSSocket* current,
                                 Namespace* namespc,
                                 const char* path) {
    while (current != nullptr) {
      ASSERT(current->address.addr.sa_family == AF_UNIX);
#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
      bool condition;
      if (path[0] == '\0') {
        condition = current->address.un.sun_path[0] == '\0' &&
                    strcmp(&(current->address.un.sun_path[1]), path + 1) == 0;
      } else {
        condition =
            File::AreIdentical(current->namespc, current->address.un.sun_path,
                               namespc, path) == File::kIdentical;
      }
      if (condition) {
        return current;
      }
#else
      if (File::AreIdentical(current->namespc, current->address.un.sun_path,
                             namespc, path) == File::kIdentical) {
        return current;
      }
#endif  // defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
      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_
