/* Copyright (c) 2014 The Regents of the University of California
 * Copyright (c) 2015 Google, Inc.
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * Echo server using select, runs on port 23.  Used for debugging select.  Based
 * on epoll_server.
 *
 * If you want to build the BSD sockets version, you need to comment out the
 * #define for PLAN9NET. */

/* Comment this out for BSD sockets */
//#define PLAN9NET

#include <stdlib.h>
#include <stdio.h>
#include <parlib/parlib.h>
#include <unistd.h>
#include <parlib/event.h>
#include <benchutil/measure.h>
#include <parlib/uthread.h>
#include <parlib/timing.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#ifdef PLAN9NET

#include <iplib/iplib.h>

#else

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#endif

int main(void)
{
	int ret;
	int afd, dfd, lcfd, listen_fd;
	char adir[40], ldir[40];
	int n;
	char buf[256];

	/* We'll use this to see if we actually did a select instead of blocking
	 * calls.  It's not 100%, but with a human on the other end, it should be
	 * fine. */
	bool has_selected = FALSE;

#ifdef PLAN9NET
	printf("Using Plan 9's networking stack\n");
	/* This clones a conversation (opens /net/tcp/clone), then reads the cloned
	 * fd (which is the ctl) to givure out the conv number (the line), then
	 * writes "announce [addr]" into ctl.  This "announce" command often has a
	 * "bind" in it too.  plan9 bind just sets the local addr/port.  TCP
	 * announce also does this.  Returns the ctlfd. */
	afd = announce9("tcp!*!23", adir, 0);

	if (afd < 0) {
		perror("Announce failure");
		return -1;
	}
	printf("Announced on line %s\n", adir);
#else
	printf("Using the BSD socket shims over Plan 9's networking stack\n");
	int srv_socket;
	struct sockaddr_in dest, srv = {0};

	srv.sin_family = AF_INET;
	srv.sin_addr.s_addr = htonl(INADDR_ANY);
	srv.sin_port = htons(23);
	socklen_t socksize = sizeof(struct sockaddr_in);

	/* Equiv to cloning a converstation in plan 9.  The shim returns the data FD
	 * for the conversation. */
	srv_socket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
	if (srv_socket < 0) {
		perror("Socket failure");
		return -1;
	}
	/* bind + listen is equiv to announce() in plan 9.  Note that the "bind"
	 * command is used, unlike in the plan9 announce. */
	/* Binds our socket to the given addr/port in srv. */
	ret = bind(srv_socket, (struct sockaddr*)&srv, sizeof(struct sockaddr_in));
	if (ret < 0) {
		perror("Bind failure");
		return -1;
	}
	/* marks the socket as a listener/server */
	ret = listen(srv_socket, 1);
	if (ret < 0) {
		perror("Listen failure");
		return -1;
	}
	printf("Listened on port %d\n", ntohs(srv.sin_port));
#endif

	/* at this point, the server has done all the prep necessary to be able to
	 * sleep/block/wait on an incoming connection. */
	fd_set rfds;

#ifdef PLAN9NET

	snprintf(buf, sizeof(buf), "%s/listen", adir);
	listen_fd = open(buf, O_PATH);
	if (listen_fd < 0) {
		perror("listen fd");
		return -1;
	}
	/* This is a little subtle.  We're putting a tap on the listen file /
	 * listen_fd.  When this fires, we get an event because of that listen_fd.
	 * But we don't actually listen or do anything to that listen_fd.  It's
	 * solely for monitoring.  We open a path, below, and we'll reattempt to do
	 * *that* operation when someone tells us that our listen tap fires. */
	FD_ZERO(&rfds);
	FD_SET(listen_fd, &rfds);
	has_selected = FALSE;
	while (1) {
		/* Opens the conversation's listen file.  This blocks til someone
		 * connects.  When they do, a new conversation is created, and that open
		 * returned an FD for the new conv's ctl.  listen() reads that to find
		 * out the conv number (the line) for this new conv.  listen() returns
		 * the ctl for this new conv.
		 *
		 * Non-block is for the act of listening, and applies to lcfd. */
		lcfd = listen9(adir, ldir, O_NONBLOCK);
		if (lcfd >= 0)
			break;
		if (errno != EAGAIN) {
			perror("Listen failure");
			return -1;
		}
		if (select(listen_fd + 1, &rfds, 0, 0, 0) < 0) {
			perror("select");
			return -1;
		}
		has_selected = TRUE;
		assert(FD_ISSET(listen_fd, &rfds));
	}
	printf("Listened and got line %s\n", ldir);
	assert(has_selected);
	/* No longer need listen_fd. */
	close(listen_fd);
	/* Writes "accept [NUM]" into the ctlfd, then opens the conv's data file and
	 * returns that fd.  Writing "accept" is a noop for most of our protocols.
	 * */
	dfd = accept9(lcfd, ldir);
	if (dfd < 0) {
		perror("Accept failure");
		return -1;
	}

#else

	FD_ZERO(&rfds);
	FD_SET(srv_socket, &rfds);
	has_selected = FALSE;
	while (1) {
		/* returns an FD for a new socket. */
		dfd = accept(srv_socket, (struct sockaddr*)&dest, &socksize);
		if (dfd >= 0)
			break;
		if (errno != EAGAIN) {
			perror("Accept failure");
			return -1;
		}
		if (select(srv_socket + 1, &rfds, 0, 0, 0) < 0) {
			perror("select");
			return -1;
		}
		has_selected = TRUE;
		assert(FD_ISSET(srv_socket, &rfds));
	}
	printf("Accepted and got dfd %d\n", dfd);
	assert(has_selected);

#endif

	/* In lieu of accept4, we set the new socket's nonblock status manually.
	 * Both OSs do this.  */
	ret = fcntl(dfd, F_SETFL, O_NONBLOCK);
	if (ret < 0) {
		perror("setfl dfd");
		exit(-1);
	}
	FD_SET(dfd, &rfds);
	/* echo until EOF */
	has_selected = FALSE;
	printf("Server read: ");
	while (1) {
		while ((n = read(dfd, buf, sizeof(buf))) > 0) {
			for (int i = 0; i < n; i++)
				printf("%c", buf[i]);
			fflush(stdout);
			/* Should select on this direction too. */
			if (write(dfd, buf, n) < 0) {
				perror("writing");
				exit(-1);
			}
		}
		if (n == 0)
			break;
		if (select(dfd + 1, &rfds, 0, 0, 0) < 0) {
			perror("select 2");
			exit(-1);
		}
		has_selected = TRUE;
		assert(FD_ISSET(dfd, &rfds));
		/* you might get a HUP, but keep on reading! */

		/* Crazy fork tests.  This will fork and let the child keep going with
		 * the connection. */
		switch (fork()) {
		case -1:
			perror("Fork");
			exit(-1);
			break;
		case 0:
			break;
		default:
			exit(0);
		}
	}
	assert(has_selected);

#ifdef PLAN9NET
	close(dfd);		/* data fd for the new conv, from listen */
	close(lcfd);	/* ctl fd for the new conv, from listen */
	close(afd);		/* ctl fd for the listening conv */
#else
	close(dfd);		/* new connection socket, from accept */
	close(srv_socket);
#endif
}
