-- webserver within a webserver demo
-- we must go deeper!

local unix = require 'unix'

function OnTerm(sig)
   -- prevent redbean core from writing a response
   unix.write(mainfd, 'redbean is shutting down\r\n')
   unix.close(mainfd)
end

function main()
   if IsClientUsingSsl() then
      ServeError(400)
      return
   end

   mainfd = GetClientFd()
   mainip = GetRemoteAddr()
   unix.sigaction(unix.SIGTERM, OnTerm)
   unix.write(mainfd, 'HTTP/1.0 200 OK\r\n' ..
              'Date: '.. FormatHttpDateTime(GetDate()) ..'\r\n' ..
              'Content-Type: text/html; charset=utf-8\r\n' ..
              'Connection: close\r\n' ..
              'Server: redbean unix\r\n' ..
              '\r\n' ..
              '<!doctype html>\r\n' ..
              '<title>redbean</title>\r\n' ..
              '<h3>webserver within a webserver demo</h3>\r\n')

   addrs = {}
   servers = {}
   pollfds = {}
   pollfds[mainfd] = unix.POLLIN

   ifs, errno = unix.siocgifconf()
   for i = 1,#ifs do
      if (IsLoopbackIp(mainip) and (IsPublicIp(ifs[i].ip) or
                                    IsPrivateIp(ifs[i].ip) or
                                    IsLoopbackIp(ifs[i].ip))) or
         (IsPrivateIp(mainip) and (IsPublicIp(ifs[i].ip) or
                                   IsPrivateIp(ifs[i].ip))) or
         (IsPublicIp(mainip) and IsPublicIp(ifs[i].ip))
      then
         server = unix.socket()
         unix.bind(server, ifs[i].ip)
         unix.listen(server)
         ip, port = unix.getsockname(server)
         addr = string.format('%s:%d', FormatIp(ip), port)
         url = string.format('http://%s', addr)
         Log(kLogInfo, string.format('listening on %s', addr))
         unix.write(mainfd, string.format(
                       'listening on <a target="_blank" href="%s">%s</a><br>\r\n',
                       url, url))
         pollfds[server] = unix.POLLIN | unix.POLLHUP
         servers[server] = true
         addrs[server] = addr
      end
   end

   while true do
      evs, errno = unix.poll(pollfds)
      if not evs then
         break
      end
      for fd,revents in pairs(evs) do
         if fd == mainfd then
            data, errno = unix.read(mainfd)
            if not data then
               Log(kLogInfo, string.format('got %s from parent client', unix.strerrno(errno)))
               -- prevent redbean core from writing a response
               unix.exit(1)
            end
            if #data == 0 then
               Log(kLogInfo, 'got hangup from parent client')
               Log(kLogInfo, 'closing server')
               -- prevent redbean core from writing a response
               unix.exit(0)
            end
            -- echo it back for fun
            unix.write(mainfd, data)
         elseif servers[fd] then
            unix.write(mainfd, string.format('preparing to accept from %d<br>\r\n', fd))
            client, clientip, clientport = unix.accept(fd)
            unix.write(mainfd, string.format('preparing to accept from %d<br>\r\n', fd))
            addr = string.format('%s:%d', FormatIp(clientip), clientport)
            addrs[client] = addr
            unix.write(mainfd, string.format('got client %s<br>\r\n', addr))
            pollfds[client] = unix.POLLIN
            evs[server] = nil
         else
            unix.write(mainfd, string.format('preparing to read from %d<br>\r\n', fd))
            data = unix.read(fd)
            unix.write(mainfd, string.format('done reading from %d<br>\r\n', fd))
            if data and #data ~= 0 then
               unix.write(mainfd, string.format('got %d bytes from %s<br>\r\n', #data, addrs[fd]))
               unix.write(fd, 'HTTP/1.0 200 OK\r\n' ..
                          'Date: '.. FormatHttpDateTime(GetDate()) ..'\r\n' ..
                          'Content-Type: text/html; charset=utf-8\r\n' ..
                          'Connection: close\r\n' ..
                          'Server: redbean unix\r\n' ..
                          '\r\n' ..
                          '<!doctype html>\r\n' ..
                          '<title>redbean</title>\r\n' ..
                          '<h3>embedded webserver demo</h3>\r\n' ..
                          'hello! this is a web server embedded in a web server!\r\n')
            end
            unix.close(fd)
            pollfds[fd] = nil
         end
      end
   end

end
main()