#include <stdlib.h>
#include <errno.h>
#include <ifaddrs.h>
#include <fcntl.h>
#include <math.h>
#include <net/if.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include <getopt.h>
#include <inttypes.h>
#include <netdb.h>

#include "log_uploader.h"
#include "kvextract.h"
#include "upload.h"
#include "utils.h"

#define DEFAULT_SERVER "https://diag.cpe.gfsvc.com"
#define COUNTER_MARKER_FILE "/tmp/loguploadcounter"
#define LOGS_UPLOADED_MARKER_FILE "/tmp/logs-uploaded"
#define DEFAULT_UPLOAD_TARGET "dmesg"
#define MAX_LOG_SIZE 8*1024*1024  // max bytes to upload in one run
#define LOG_BUF_EXTRA 65536       // extra bytes for extra compression slop
#define DEV_KMSG_PATH "/dev/kmsg"
#define NTP_SYNCED_PATH "/tmp/ntp.synced"
#define VERSION_PATH "/etc/version"
#define SERIAL_PATH "/tmp/serial"
#define PLATFORM_PATH "/tmp/platform"
// 8192 is the size of the buffer used in printk.c to store a line read from
// /dev/kmsg before copying it into our userspace buffer
#define LOG_LINE_BUFFER_SIZE 8192

// Use level 1 so we compress for speed, not size since we have lots
// of bandwidth for uploading but CPU cycles are something we want to
// conserve.
#define ZLIB_COMPRESS_LEVEL 1

static const char *interfaces_to_check[] = { "br0", "eth0", "man", "pon0" };
static int num_interfaces = sizeof(interfaces_to_check) /
  sizeof(interfaces_to_check[0]);

volatile static int interrupted = 0;

static void got_alarm(int sig) {
  interrupted = 1;
}

// To allow overriding for testing.
int getnameinfo_resolver(const struct sockaddr* sa, socklen_t salen, char* host,
    size_t hostlen, char* serv, size_t servlen, int flags) {
  return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
}

// To allow overriding for testing, gets the MAC of a network interface.
int iface_to_mac(const char* iface, char* buf, int len) {
  // xx:xx:xx:xx:xx:xx format comes back, 17 chars + terminator
  if (len < 18)
    return -1;
  struct ifreq ifreq;
  int fd;
  memset(&ifreq, 0, sizeof(ifreq));
  fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
  if (strlen(iface) + 1 > sizeof(ifreq.ifr_name))
    return -1;
  strcpy(ifreq.ifr_name, iface);
  if (ioctl(fd, SIOCGIFHWADDR, &ifreq) == -1) {
    close(fd);
    return -1;
  } else {
    close(fd);
    snprintf(buf, len, "%02x:%02x:%02x:%02x:%02x:%02x",
        ifreq.ifr_hwaddr.sa_data[0], ifreq.ifr_hwaddr.sa_data[1],
        ifreq.ifr_hwaddr.sa_data[2], ifreq.ifr_hwaddr.sa_data[3],
        ifreq.ifr_hwaddr.sa_data[4], ifreq.ifr_hwaddr.sa_data[5]);
    return 0;
  }
}

int standard_read(char* buffer, int len, void* user_data) {
  return read(*((int*) user_data), buffer, len);
}

static void usage(const char* progname) {
  fprintf(stderr, "\nUsage: %s [options...]\n", progname);
  fprintf(stderr, " --server URL    Server URL [" DEFAULT_SERVER "]\n");
  fprintf(stderr, " --all           Upload entire logs, not just new data\n");
  fprintf(stderr, " --logtype TYPE  Tell server which log category this is\n");
  fprintf(stderr, " --freq SECS     Upload logs every SECS seconds [60]\n");
  fprintf(stderr, " --stdout        Print to stdout instead of uploading\n");
  fprintf(stderr,
          " --stdin NAME    Get data from stdin, not /dev/kmsg, and\n"
          "                   name uploaded file NAME rather than 'dmesg'\n");
  exit(EXIT_SUCCESS);
}

static int parse_args(struct upload_config* config, int argc,
    char* const argv[]) {
  int opt = 0;
  static struct option long_options[] = {
    { "server", required_argument, 0, 's' },
    { "all", no_argument, 0, 'a' },
    { "logtype", required_argument, 0, 'l' },
    { "freq", required_argument, 0, 'f' },
    { "stdout", no_argument, 0, 'd' },
    { "stdin", required_argument, 0, 'i' },
    { 0, 0, 0, 0}
  };

  while (1) {
    opt = getopt_long(argc, argv, "", long_options, NULL);
    if (opt == -1)
      break;

    switch (opt) {
      case 'a':
        config->upload_all = 1;
        break;
      case 'd':
        config->use_stdout = 1;
        break;
      case 's':
        snprintf(config->server, sizeof(config->server), "%s", optarg);
        break;
      case 'i':
        config->use_stdin = 1;
        snprintf(config->upload_target, sizeof(config->upload_target), "%s",
            optarg);
        break;
      case 'l':
        snprintf(config->logtype, sizeof(config->logtype), "%s", optarg);
        break;
      case 'f':
        config->freq = atoi(optarg);
        if (config->freq < 0) {
          fprintf(stderr, "fatal: freq must be >= 0\n");
          return -1;
        }
        break;
      default:
        return -1;
    }
  }
  if (optind < argc)
    return -1; // extraneous non-option arguments
  return 0;
}

static int pick_delay(struct upload_config* config) {
  // Randomize the sleep time to be near the specified amount, +/- 1/12th.
  // (1/12th is weird, but it means +/- 5 for 60 seconds, which is nice).
  int variance = config->freq / 12;
  return ((config->freq - variance) +
          (random() % (variance * 2 + 1)));
}

int main(int argc, char* const argv[]) {
  setvbuf(stdout, (char *) NULL, _IOLBF, 0);

  struct upload_config config;
  memset(&config, 0, sizeof(config));

  snprintf(config.server, sizeof(config.server), "%s", DEFAULT_SERVER);
  snprintf(config.upload_target, sizeof(config.upload_target), "%s",
        DEFAULT_UPLOAD_TARGET);

  if (argc > 1) {
    if (parse_args(&config, argc, argv) < 0) {
      usage(argv[0]);
      return 99;
    }
  }

  struct sigaction sa = {};
  sa.sa_handler = got_alarm;
  sigaction(SIGALRM, &sa, NULL);

  // Initialize the random number generator
  srandom(getpid() ^ time(NULL));

  // Allocate this once and re-use it every time
  char* log_buffer = (char*) malloc(MAX_LOG_SIZE + LOG_BUF_EXTRA);
  if (!log_buffer) {
    fprintf(stderr, "Failed to allocate log_buffer!\n");
    return 98;
  }

  int kmsg_read_fd = 0;
  if (!config.use_stdin) {
    // We never actually close this, it'll get done when the process exits.
    // Use nonblocking mode so we know when we're consumed all the recent data.
    kmsg_read_fd = open("/dev/kmsg", O_RDONLY | O_NONBLOCK);
    if (kmsg_read_fd < 0) {
      perror("/dev/kmsg");
      return 1;
    }
  }

  // In the kernel struct devkmsg_user this is the size of the buffer
  // they use to read a line and then copy it to us, so it won't be any
  // bigger than this.
  char line_buffer[LOG_LINE_BUFFER_SIZE];
  unsigned long total_read;
  z_stream zstrm;
  memset(&zstrm, 0, sizeof(zstrm));

  struct log_parse_params parse_params;
  memset(&parse_params, 0, sizeof(parse_params));
  parse_params.config = &config;
  parse_params.user_data = &kmsg_read_fd;
  parse_params.read_log_data = standard_read;
  parse_params.dev_kmsg_path = DEV_KMSG_PATH;
  parse_params.version_path = VERSION_PATH;
  parse_params.ntp_synced_path = NTP_SYNCED_PATH;
  // This'll set it to zero if it can't read the file which is fine.
  parse_params.last_log_counter = read_file_as_uint64(COUNTER_MARKER_FILE);
  parse_params.log_buffer = log_buffer;
  parse_params.line_buffer = line_buffer;
  parse_params.line_buffer_size = sizeof(line_buffer);

  while (1) {
    char* log_data_to_use;
    if (config.use_stdin) {
      // Read in all the data from stdin
      int num_read;
      total_read = num_read = 0;
      interrupted = 0;
      alarm(pick_delay(&config));
      while ((num_read = read(STDIN_FILENO, log_buffer + total_read,
              MAX_LOG_SIZE - total_read)) > 0 && !interrupted) {
        total_read += num_read;
      }
      if (num_read < 0 && errno != EINTR) {
        perror("stdin");
        return 2;
      }
      if (num_read == 0 && total_read == 0) {
        fprintf(stderr, "stdin: end of input. done.\n");
        return 0;
      }
      log_data_to_use = log_buffer;
    } else {
      // Remove the marker file to indicate we've completed the upload process.
      remove(LOGS_UPLOADED_MARKER_FILE);

      // Normal logs processing, write out the general marker data.
      // We only need to write this out if we're doing the first upload
      // otherwise it'll have been written right after we did the last one.
      if (parse_params.last_log_counter == 0 &&
          logmark_once(DEV_KMSG_PATH, VERSION_PATH,
          NTP_SYNCED_PATH)) {
        fprintf(stderr, "failed to execute logmark-once properly\n");
        return 3;
      }

      parse_params.total_read = MAX_LOG_SIZE;
      log_data_to_use = parse_and_consume_log_data(&parse_params);
      if (!log_data_to_use) {
        fprintf(stderr, "failed with logs parsing, abort!\n");
        return 4;
      }
      total_read = parse_params.total_read;
    }

    // Now we've read all of the log data into our buffer, proceed
    // with uploading or outputting it.

    fprintf(stderr, "uploading %lu bytes of logs.\n", total_read);
    if (config.use_stdout) {
      // Just print the whole thing to stdout.  Note: might be binary.
      fwrite(log_data_to_use, total_read, 1, stdout);
    } else {
      struct ifaddrs* ifaddr;
      if (getifaddrs(&ifaddr)) {
        perror("getifaddrs");
        return 5;
      }

      struct kvextractparams kvparams;
      memset(&kvparams, 0, sizeof(kvparams));
      kvparams.interfaces_to_check = interfaces_to_check;
      kvparams.num_interfaces = num_interfaces;
      kvparams.ifaddr = ifaddr;
      kvparams.platform_path = PLATFORM_PATH;
      kvparams.serial_path = SERIAL_PATH;
      kvparams.name_info_resolver = getnameinfo_resolver;
      kvparams.interface_to_mac = iface_to_mac;
      kvparams.logtype = config.logtype;
      struct kvpair* kvpairs = extract_kv_pairs(&kvparams);
      freeifaddrs(ifaddr);
      if (!kvpairs) {
        fprintf(stderr, "failure extracting kv pairs, abort\n");
        return 6;
      }

      // Adjust this if we moved the pointer.
      unsigned long compressed_size = MAX_LOG_SIZE + LOG_BUF_EXTRA -
        (log_data_to_use - log_buffer);
      int comp_result = deflate_inplace(&zstrm, (unsigned char*)log_data_to_use,
          total_read, &compressed_size);
      if (comp_result != Z_OK) {
        fprintf(stderr, "fatal: deflate_inplace failed\n");
        return 7;
      }

      int upload_res = upload_file(config.server, config.upload_target,
            log_data_to_use, compressed_size, kvpairs);
      free_kv_pairs(kvpairs);
      if (upload_res) {
        fprintf(stderr, "upload_file failed\n");
        return 8;
      }
      if (write_file_as_uint64(COUNTER_MARKER_FILE,
            parse_params.last_log_counter)) {
        fprintf(stderr, "unable to write out last log counter\n");
        return 9;
      }
      // Write the marker file to indicate we finished the upload.
      int marker_fd = open(LOGS_UPLOADED_MARKER_FILE, O_CREAT | O_WRONLY,
          RW_FILE_PERMISSIONS);
      if (marker_fd >= 0)
        close(marker_fd);
    }

    if (!config.use_stdin) {
      if (write_to_file(DEV_KMSG_PATH, LOG_MARKER_END_LINE) < 0) {
        perror("end marker");
        return 10;
      }
    }

    if (!config.freq) {
      break;
    } else if (!config.use_stdin) {
      // if using stdin, we want to read incrementally instead.
      sleep(pick_delay(&config));
    }
  }
  free(log_buffer);
  return 0;
}
