#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include <getopt.h>

#include "spectral.h"

static void load_default_config(spectral_config* config);

static int load_config(spectral_config* config);

static void usage(const char* progname);

static int parse_args(spectral_config* config, int argc, char* const argv[]);

static void verify_config(spectral_config* config);

static int execute_full_scan(spectral_config* config, bucket_results* buckets);

static int send_control(const char* message);

static int go_offchannel(const spectral_config* config, int freq);

static char* collect_results(ssize_t* total);

static void append_results(const char* raw_data, ssize_t size,
                              bucket_results* buckets);

static void post_buckets(const bucket_results* result);

static int calc_square_sum(const uint8_t* data, int num, uint8_t exp);

static void dump_raw_data(spectral_config* config, char* data, ssize_t size);

// Only for reading non-negative numbers, returns -1 if file doesn't exist.
static int32_t read_file_as_int(char *file_path);

int main(int argc, char* const argv[]) {
  spectral_config config;
  bucket_results buckets;
  int rv;
  int ignore_fs_config = 0;
  setvbuf(stdout, (char *) NULL, _IOLBF, 0);

  printf("Starting background spectral scanner\n");
  load_default_config(&config);
  if (argc > 1) {
    if (parse_args(&config, argc, argv) < 0) {
      usage(argv[0]);
      return 1;
    }
    // This allows for using it in a way that overrides what's
    // configured as the settings in the filesystem.
    ignore_fs_config = 1;
    verify_config(&config);
  }
  while (1) {
    if (!ignore_fs_config) {
      if (load_config(&config))
        verify_config(&config);
    }

    if (config.scan_period_millis == 0) {
      // This is how we can disable it, but setting the overall
      // scan period to zero. We then recheck our config in 6 minutes.
      usleep(360000);
      continue;
    }

    rv = execute_full_scan(&config, &buckets);

    if (rv >= 0) {
      post_buckets(&buckets);
    } else {
      fprintf(stderr, "Failure with full scan\n");
    }

    usleep(config.scan_period_millis * 1000);
  }
  return 0;
}

static void load_default_config(spectral_config* config) {
  config->offchan_dur_millis = 100;
  config->scan_period_millis = 300000;
  config->channel_switch_delay_millis = 1000;
  config->dump_dir[0] = '\0';
  config->dump_count = 0;
}

static int load_config(spectral_config* config) {
  int rv = 0;
  int32_t config_value = read_file_as_int("/tmp/spectral_offchannel_duration");
  if (config_value >= 0) {
    config->offchan_dur_millis = config_value;
    rv =1;
  }
  config_value = read_file_as_int("/tmp/spectral_offchannel_switch_delay");
  if (config_value >= 0) {
    config->channel_switch_delay_millis = config_value;
    rv = 1;
  }
  config_value = read_file_as_int("/tmp/spectral_scan_period");
  if (config_value >= 0) {
    config->scan_period_millis = config_value;
    rv = 1;
  }
  return rv;
}

static void usage(const char* progname) {
  printf("%s [--offchan_dur dur] [--scan_period period] "
      "[--dump_dir dir] [--channel_switch_delay delay]\n", progname);
  exit(1);
}

static int parse_args(spectral_config* config, int argc, char* const argv[]) {
  int opt = 0, len;
  static struct option long_options[] = {
    { "offchan_dur", required_argument, 0, 'o' },
    { "scan_period", required_argument, 0, 's' },
    { "channel_switch_delay", required_argument, 0, 'c' },
    { "dump_dir", required_argument, 0, 'd' },
    { 0, 0, 0, 0}
  };

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

    switch (opt) {
      case 'o':
        config->offchan_dur_millis = atoi(optarg);
        break;
      case 's':
        config->scan_period_millis = atoi(optarg);
        break;
      case 'c':
        config->channel_switch_delay_millis = atoi(optarg);
        break;
      case 'd':
       len = snprintf(config->dump_dir, sizeof(config->dump_dir) - 1,
           "%s", optarg);
       if (len >= sizeof(config->dump_dir) - 1) {
         fprintf(stderr, "Dump path is too long\n");
         return -1;
       }
       if (config->dump_dir[len - 1] != '/') {
         config->dump_dir[len] = '/';
         config->dump_dir[len + 1] = '\0';
       }
       break;
     default:
       return -1;
    }
  }
  if (optind < argc)
    return -1; // extraneous non-option arguments
  return 0;
}

static void verify_config(spectral_config* config) {
  if (config->offchan_dur_millis <= 0) {
    fprintf(stderr, "Invalid offchan_dur_millis in spectral config %d\n",
        config->offchan_dur_millis);
    config->offchan_dur_millis = 100;
  }
  if (config->scan_period_millis < 0) {
    fprintf(stderr,
        "Invalid scan_period_millis in spectral config %d\n",
        config->scan_period_millis);
    config->scan_period_millis = 300000;
  }
  if (config->channel_switch_delay_millis <= 0) {
    fprintf(stderr,
        "Invalid channel_switch_delay in spectral config %d\n",
        config->channel_switch_delay_millis);
    config->channel_switch_delay_millis = 1000;
  }
  printf("Loaded spectral config offchan_dur %d scan_period %d"
      " channel_switch %d dump_dir %s\n",
      config->offchan_dur_millis, config->scan_period_millis,
      config->channel_switch_delay_millis, config->dump_dir);
}

static int execute_full_scan(spectral_config* config, bucket_results* buckets) {
  int freq, rv;
  ssize_t total_size;
  char* raw_data;

  if (buckets)
    memset(buckets, 0, sizeof(*buckets));

  for (freq = MIN_SCAN_FREQ; freq <= MAX_SCAN_FREQ; freq += FREQ_STEP) {
    // First we need to enable background scanning.
    rv = send_control("background");
    if (rv < 0) {
      fprintf(stderr, "Failed to set background scanning\n");
      return -1;
    }

    // Switch the AP into offchannel mode briefly.
    rv = go_offchannel(config, freq);
    if (rv < 0) {
      fprintf(stderr, "Failed to do offchannel scan\n");
      return -1;
    }

    // Trigger the actual scan.
    rv = send_control("trigger");
    if (rv < 0) {
      fprintf(stderr, "Failure triggering the spectral scan\n");
      return -1;
    }

    // Wait for the scan to complete.
    usleep(config->offchan_dur_millis * 1000);

    // Disable scanning.
    rv = send_control("disable");
    if (rv < 0) {
      fprintf(stderr, "Failure disabling the spectral scan\n");
      return -1;
    }

    total_size = 0;
    raw_data = collect_results(&total_size);
    if (!raw_data) {
      fprintf(stderr, "Failure collecting scan data results\n");
      return -1;
    }

    append_results(raw_data, total_size, buckets);
    if (config->dump_dir[0]) {
      dump_raw_data(config, raw_data, total_size);
    }
    free(raw_data);

    // Wait to do another cycle
    usleep(config->channel_switch_delay_millis * 1000);
  }
  return 0;
}

static void dump_raw_data(spectral_config* config, char* data, ssize_t size) {
  int dump_fd;
  ssize_t written;
  char target_file[MAX_PATH + 20];

  snprintf(target_file, sizeof(target_file), "%sspectral-%d", config->dump_dir,
      config->dump_count);
  config->dump_count++;
  dump_fd = open(target_file, O_WRONLY | O_TRUNC | O_CREAT, 0666);
  if (dump_fd < 0) {
    fprintf(stderr, "Could not open dump file at %s errno %d\n",
        target_file, errno);
    return;
  }
  written = write(dump_fd, data, size);
  if (size != written) {
    fprintf(stderr, "Incomplete write to dump file %s wrote %zd length %zd\n",
        target_file, written, size);
  }
  if (close(dump_fd) < 0) {
    fprintf(stderr, "Failure closing dump file %s\n", target_file);
  }
}

static int send_control(const char* message) {
  int len, scan_ctl_fd, rv;
  ssize_t count;

  scan_ctl_fd = open(
      "/sys/kernel/debug/ieee80211/phy0/ath9k/spectral_scan_ctl",
      O_WRONLY | O_TRUNC);
  if (scan_ctl_fd < 0) {
    fprintf(stderr, "Failure opening spectral_scan_ctl: %d\n", errno);
    return -1;
  }
  len = strlen(message);
  count = write(scan_ctl_fd, message, len);
  rv = close(scan_ctl_fd);
  if (len != count) {
    fprintf(stderr, "Incomplete write to spectral_scan_ctl written %zd len %d",
        count, len);
    return -1;
  }
  if (rv < 0) {
    fprintf(stderr, "Failure closing spectral_scan_ctl: %d\n", errno);
    return -1;
  }
  return 0;
}

static int go_offchannel(const spectral_config* config, int freq) {
  char* iwcmd[7];
  char freq_str[16];
  char dwell_str[16];
  pid_t pid;
  int fd, maxfd;

  printf("Performing wifi spectral scan at freq %d\n", freq);
  iwcmd[0] = "iw";
  iwcmd[1] = "dev";
  iwcmd[2] = "wlan0";
  iwcmd[3] = "offchannel";
  snprintf(freq_str, sizeof(freq_str), "%d", freq);
  iwcmd[4] = freq_str;
  snprintf(dwell_str, sizeof(dwell_str), "%d", config->offchan_dur_millis);
  iwcmd[5] = dwell_str;
  iwcmd[6] = NULL;
  pid = fork();
  if (pid != -1) {
    if (!pid) { // child
      // Close all descriptors except stdin, stdout, stderr
      maxfd = sysconf(_SC_OPEN_MAX);
      for (fd = 3; fd < maxfd; ++fd) {
        close(fd);
      }
      execvp(iwcmd[0], (char* const *)iwcmd);
      // It won't reach this unless there was an error
      fprintf(stderr, "Error executing %s errno: %d\n", iwcmd[0], errno);
      exit(1);
    } else {
      // Wait for it to finish
      waitpid(pid, NULL, 0);
      return 0;
    }
  } else {
    fprintf(stderr, "Error executing child process errno: %d\n", errno);
    return -1;
  }
}

static char* collect_results(ssize_t* total) {
  char *buf = NULL, *buf_tmp = NULL;
  const ssize_t read_size = 4096;
  ssize_t count;
  int result_fd = open(
      "/sys/kernel/debug/ieee80211/phy0/ath9k/spectral_scan0",
      O_RDONLY);
  if (result_fd < 0) {
    fprintf(stderr, "Error opening spectral_scan0 of %d\n", errno);
    return NULL;
  }
  *total = 0;
  while (1) {
    buf_tmp = realloc(buf, *total + read_size);
    if (!buf_tmp) {
      fprintf(stderr, "Failure reallocating read buffer\n");
      if (buf)
        free(buf);
      *total = 0;
      close(result_fd);
      return NULL;
    }
    buf = buf_tmp;
    count = read(result_fd, buf + *total, read_size);
    *total += count;
    if (count < 0) {
      fprintf(stderr, "Failure reading spectral_scan0 of %d\n", errno);
      *total = 0;
      free(buf);
      close(result_fd);
      return NULL;
    }
    if (count < read_size)
      break;
  }
  close(result_fd);
  //printf("Succesfully read %d bytes of scan data\n", *total);
  return buf;
}

static void append_results(const char* raw_data, ssize_t size,
                          bucket_results* buckets) {
  uint16_t freq;
  uint64_t timestamp;
  int i, bin_offset, square_sum, base_value;
  int power_bucket_index, freq_bucket_index;
  float bucket_max = -200, curr_signal;
  fft_data_tlv* tlv;
  fft_data* curr_fft_data;
  size_t data_len;
  const char* pos = raw_data;
  while (pos - raw_data < size) {
    tlv = (fft_data_tlv*) pos;
    data_len = sizeof(fft_data_tlv) + be16toh(tlv->len);
    pos += data_len;
    if (tlv->type != 1) {
      // 1 is the type code for the HT20 data we understand.
      fprintf(stderr, "Invalid type code in scan data of %d\n", tlv->type);
      continue;
    }
    if (data_len != sizeof(fft_data)) {
      fprintf(stderr, "Invalid data length in scan data of %zd\n", data_len);
      continue;
    }
    curr_fft_data = (fft_data*) tlv;
    // Fix the byte ordering on the data fields larger than 8 bits.
    freq = be16toh(curr_fft_data->freq);
    timestamp = be64toh(curr_fft_data->timestamp);

    if (buckets) {
      buckets->timestamp = timestamp;
    }
    bin_offset = FREQ_STEP_BIN_OFFSET * (freq - MIN_SCAN_FREQ) / FREQ_STEP;
    if (bin_offset < 0 || bin_offset >= NUM_OVERALL_BINS) {
      fprintf(stderr, "Invalid frequency bin %d from freq %d\n",
          bin_offset, freq);
      continue;
    }
    square_sum = calc_square_sum(curr_fft_data->fft_values,
                                     NUM_SAMPLE_BINS,
                                     curr_fft_data->max_exponent);
    if (square_sum == 0) {
      // Sometimes the data is all empty so the square sum is zero,
      // we can't do anything correct in this case since this is just
      // bad data coming from the driver so just skip it.
      // This happens every so often..no need to log it.
      //fprintf(stderr, "Skipping data chunk due to zero sum\n");
      continue;
    }
    for (i = 0; i < NUM_SAMPLE_BINS; ++i) {
      base_value = curr_fft_data->fft_values[i] << curr_fft_data->max_exponent;
      if (base_value == 0)
        base_value = 1;
      curr_signal = curr_fft_data->noise + curr_fft_data->rssi +
        20 * log10f(base_value) - 10 * log10f(square_sum);
      if (buckets) {
        if (i % BINS_PER_BUCKET == 0)
          bucket_max = -200;
        if (curr_signal > bucket_max)
          bucket_max = curr_signal;
        if ((i + 1) % BINS_PER_BUCKET == 0) {
          // We have the max for this bucket, update the info
          freq_bucket_index = (bin_offset + i + 1 - BINS_PER_BUCKET) /
              BINS_PER_BUCKET;
          if (bucket_max <= LOWER_POWER_BUCKET_MIN)
            power_bucket_index = 0;
          else if (bucket_max >= UPPER_POWER_BUCKET_MAX)
            power_bucket_index = NUM_POWER_BUCKETS - 1;
          else
            power_bucket_index = (((int) bucket_max) - LOWER_POWER_BUCKET_MIN) /
              POWER_BUCKET_STEP;
          buckets->bucket_count[freq_bucket_index][power_bucket_index]++;
          buckets->total[freq_bucket_index]++;
        }
      }
    }
  }
}

static int calc_square_sum(const uint8_t* data, int num, uint8_t exp) {
  int i, curr, rv = 0;
  for (i = 0; i < num; ++i) {
    curr =  data[i] << exp;
    rv += (curr * curr);
  }
  return rv;
}

static void post_buckets(const bucket_results* result) {
  int i, j, k, perct, overall_total, bucket_total;
  // This prints out the buckets as 5 MHz intervals and doesn't coalesce
  // the data into each Wifi channel itself. It may be useful again so I'm
  // going to leave it here just in case.
  if (0) {
    for (i = 0; i < NUM_FREQ_BUCKETS; i++) {
      if (result->total[i]) {
        printf("%d MHz\n", MIN_OVERALL_FREQ + (i * FREQ_BUCKET_STEP));
        for (j = 0; j < NUM_POWER_BUCKETS; ++j) {
          perct = result->bucket_count[i][j] * 100 / result->total[i];
          if (perct > 0)
            printf(" %3d", perct);
          else
            printf("    ");
        }
        printf("\n");
      }
    }
  }

  // We start at 2 because we are going over all the wifi channels
  // here and the first two will get added into the first channel.
  // We stop one short of the end because that one will get included in
  // channel 11.
  for (i = 2; i < NUM_FREQ_BUCKETS - 1; i++) {
    printf("fft-%2d:", i - 1);
    overall_total = 0;
    for (k = -2; k < 2; k++) {
      overall_total += result->total[i + k];
    }
    for (j = 0; j < NUM_POWER_BUCKETS; ++j) {
      bucket_total = 0;
      for (k = -2; k < 2; k++) {
        bucket_total += result->bucket_count[i + k][j];
      }
      perct = bucket_total * 100 / overall_total;
      if (perct > 0)
        printf(" %3d", perct);
      else
        printf("    ");
    }
    printf("\n");
  }
}

int32_t read_file_as_int(char* file_path) {
  char buf[64];
  int num_read, fd = open(file_path, O_RDONLY);
  if (fd < 0)
    return -1;
  num_read = read(fd, buf, sizeof(buf) -1);
  if (num_read > 0) {
    buf[num_read] = '\0';
    return atoi(buf);
  }
  return -1;
}
