// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

int server(const char* service) {
  int port = atoi(service);
  printf("listen on port %d\n", port);

  int s = socket(AF_INET6, SOCK_STREAM, 0);
  if (s < 0) {
    printf("socket failed (errno = %d)\n", errno);
    return -1;
  }

  struct sockaddr_in6 addr;
  memset(&addr, 0, sizeof(addr));
  addr.sin6_family = AF_INET6;
  addr.sin6_addr = in6addr_any;  // works with IPv4
  addr.sin6_port = htons((uint16_t)port);

  if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
    printf("bind failed (errno = %d)\n", errno);
    close(s);
    return -1;
  }

  if (listen(s, 1) < 0) {
    printf("listen failed\n");
    close(s);
    return -1;
  }

  fd_set active_readfds, active_writefds, active_exceptfds;
  FD_ZERO(&active_readfds);
  FD_ZERO(&active_writefds);
  FD_ZERO(&active_exceptfds);

  FD_SET(s, &active_readfds);
  int nwatch = s + 1;

  int ret = 0;
  for (;;) {
    fd_set readfds = active_readfds;
    fd_set writefds = active_writefds;
    fd_set exceptfds = active_exceptfds;

    int nready = select(nwatch, &readfds, &writefds, &exceptfds, NULL);
    if (nready < 0) {
      printf("select failed (errno = %d)\n", errno);
      ret = -1;
      goto end;
    }

    if (FD_ISSET(s, &readfds)) {
      --nready;
      // a connection is waiting
      socklen_t addrlen = sizeof(addr);
      int conn = accept(s, (struct sockaddr*)&addr, &addrlen);
      if (conn < 0) {
        close(s);
        printf("accept failed (errno = %d)\n", errno);
        ret = -1;
        goto end;
      }
      char str[INET6_ADDRSTRLEN];
      struct sockaddr_in6* sin6 = (struct sockaddr_in6*)&addr;
      printf("connected from %s\n", inet_ntop(AF_INET6, &sin6->sin6_addr, str, sizeof(str)));

      FD_SET(conn, &active_readfds);
      if (nwatch < (conn + 1))
        nwatch = conn + 1;
    }

    for (int fd = 0; fd < nwatch; fd++) {
      if (nready == 0)
        break;

      if (fd == s)
        continue;

      if (FD_ISSET(fd, &readfds)) {
        --nready;
        // data is ready to read
        char buf[128];
        int done = 0;
        ssize_t nread = read(fd, buf, sizeof(buf));
        if (nread == 0) {
          done = 1;
        } else if (nread < 0) {
          printf("read failed on fd %d (%zd)\n", fd, nread);
          done = 1;
        } else {
          int nwrite = 0;
          while (nwrite < nread) {
            ssize_t n = write(fd, buf + nwrite, nread - nwrite);
            if (n < 0) {
              printf("write failed on fd %d (%zd)\n", fd, n);
              done = 1;
              break;
            }
            nwrite += n;
          }
        }
        if (done) {
          close(fd);
          FD_CLR(fd, &active_readfds);
        }
      }
    }
  }
end:
  for (int i = 0; i < nwatch; i++) {
    if (FD_ISSET(i, &active_readfds)) {
      close(i);
    }
  }

  return ret;
}

void usage(void) { printf("usage: selecttest port\n"); }

int main(int argc, char** argv) {
  if (argc < 2) {
    usage();
    return -1;
  }
  return server(argv[1]);
}
