// 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 "netsvc.h"

#include <fcntl.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/zx/clock.h>
#include <unistd.h>
#include <zircon/boot/netboot.h>
#include <zircon/syscalls.h>
#include <zircon/time.h>

#include <algorithm>
#include <climits>
#include <cstdio>
#include <cstring>
#include <string>

#include <fbl/unique_fd.h>
#include <inet6/inet6.h>
#include <inet6/netifc.h>

#include "args.h"
#include "debuglog.h"
#include "netboot.h"
#include "src/sys/lib/stdout-to-debuglog/cpp/stdout-to-debuglog.h"
#include "tftp.h"

#ifndef ENABLE_SLAAC
// SLAAC RA's are disabled by default as they intefere with tests in environments where there are
// many devices on the same LAN.
#define ENABLE_SLAAC 0
#endif

static bool g_netbootloader = false;

// When false (default), will only respond to a limited number of commands.
// Currently, NB_QUERY (to support netls and netaddr), as well as responding to
// ICMP as usual.
static bool g_all_features = false;

static char g_nodename[HOST_NAME_MAX];

bool netbootloader() { return g_netbootloader; }
bool all_features() { return g_all_features; }
const char* nodename() { return g_nodename; }

void udp6_recv(void* data, size_t len, const ip6_addr_t* daddr, uint16_t dport,
               const ip6_addr_t* saddr, uint16_t sport) {
  bool mcast = (memcmp(daddr, &ip6_ll_all_nodes, sizeof(ip6_addr_t)) == 0);

  if (!all_features()) {
    if (dport != NB_SERVER_PORT) {
      // Only some netboot commands allowed in limited mode.
      return;
    }
  }

  switch (dport) {
    case NB_SERVER_PORT:
      netboot_recv(data, len, mcast, daddr, dport, saddr, sport);
      break;
    case DEBUGLOG_ACK_PORT:
      debuglog_recv(data, len, mcast);
      break;
    case NB_TFTP_INCOMING_PORT:
    case NB_TFTP_OUTGOING_PORT:
      tftp_recv(data, len, daddr, dport, saddr, sport);
      break;
  }
}

void netifc_recv(void* data, size_t len) { eth_recv(data, len); }

bool netifc_send_pending() {
  if (!tftp_has_pending()) {
    return false;
  }
  tftp_send_next();
  return tftp_has_pending();
}

static const char* zedboot_banner =
    "              _ _                 _   \n"
    "             | | |               | |  \n"
    "  _______  __| | |__   ___   ___ | |_ \n"
    " |_  / _ \\/ _` | '_ \\ / _ \\ / _ \\| __|\n"
    "  / /  __/ (_| | |_) | (_) | (_) | |_ \n"
    " /___\\___|\\__,_|_.__/ \\___/ \\___/ \\__|\n"
    "                                      \n"
    "\n";

int main(int argc, char** argv) {
  zx_status_t status = StdoutToDebuglog::Init();
  if (status != ZX_OK) {
    printf("Failed to redirect stdout to debuglog, assuming test environment and continuing\n");
  }

  fbl::unique_fd svc_root(open("/svc", O_RDWR | O_DIRECTORY));
  fdio_cpp::UnownedFdioCaller caller(svc_root.get());

  NetsvcArgs args;
  const char* error;
  if (ParseArgs(argc, argv, *caller.channel(), &error, &args) < 0) {
    printf("netsvc: fatal error: %s\n", error);
    return -1;
  };
  if (args.disable) {
    printf("netsvc: Disabled. Exiting.\n");
    return 0;
  }

  bool print_nodename_and_exit = args.print_nodename_and_exit;
  bool should_advertise = args.advertise;
  g_netbootloader = args.netboot;
  g_all_features = args.all_features;
  const char* interface = args.interface.empty() ? nullptr : args.interface.c_str();

  if (g_netbootloader && !g_all_features) {
    printf("netsvc: fatal: --netboot requires --all-features\n");
    return -1;
  }

  if (g_all_features) {
    if (debuglog_init() < 0) {
      return -1;
    }
  }

  printf("netsvc: running in %s mode\n", g_all_features ? "full" : "limited");

  gethostname(g_nodename, sizeof(g_nodename));

  printf("netsvc: nodename='%s'\n", g_nodename);

  if (print_nodename_and_exit) {
    return 0;
  }

  if (interface != nullptr) {
    printf("netsvc: looking for interface %s\n", interface);
  }

  if (!should_advertise) {
    printf("netsvc: will not advertise\n");
  }

  for (;;) {
    if (netifc_open(interface) != 0) {
      printf("netsvc: fatal error initializing network\n");
      return -1;
    }

    if (g_netbootloader) {
      printf("%szedboot: version: %s\n\n", zedboot_banner, BOOTLOADER_VERSION);
    }

    printf("netsvc: start\n");

    zx_time_t advertise_next_timeout = ZX_TIME_INFINITE;
    if (g_netbootloader && should_advertise) {
      advertise_next_timeout = zx::clock::get_monotonic().get();
    }

    for (;;) {
      if (netifc_poll(
              std::min({advertise_next_timeout, debuglog_next_timeout(), tftp_next_timeout()}))) {
        printf("netsvc: netifc_poll() failed - terminating\n");
        break;
      }

      zx_time_t now = zx::clock::get_monotonic().get();
      if (now > advertise_next_timeout) {
#if ENABLE_SLAAC
        send_router_advertisement();
#endif
        netboot_advertise(g_nodename);
        advertise_next_timeout = zx_deadline_after(ZX_SEC(1));
      }
      if (now > debuglog_next_timeout()) {
        debuglog_timeout_expired();
      }
      if (now > tftp_next_timeout()) {
        tftp_timeout_expired();
      }
    }
    netifc_close();
  }
}
