// Copyright 2018 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 <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <fuchsia/boot/c/fidl.h>
#include <getopt.h>
#include <inttypes.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/zx/channel.h>
#include <lib/zx/clock.h>
#include <lib/zx/resource.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>
#include <unistd.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>

#include <fbl/vector.h>

#include "stress_test.h"

namespace {

zx_status_t get_root_resource(zx::resource* root_resource) {
  zx::channel local, remote;
  zx_status_t status = zx::channel::create(0, &local, &remote);
  if (status != ZX_OK) {
    return status;
  }
  status = fdio_service_connect("/svc/fuchsia.boot.RootResource", remote.release());
  if (status != ZX_OK) {
    fprintf(stderr, "ERROR: Cannot open fuchsia.boot.RootResource: %s (%d)\n",
            zx_status_get_string(status), status);
    return ZX_ERR_NOT_FOUND;
  }

  zx_handle_t h;
  zx_status_t fidl_status = fuchsia_boot_RootResourceGet(local.get(), &h);

  if (fidl_status != ZX_OK) {
    fprintf(stderr, "ERROR: Cannot obtain root resource: %s (%d)\n",
            zx_status_get_string(fidl_status), fidl_status);
    return fidl_status;
  }

  root_resource->reset(h);

  return ZX_OK;
}

zx_status_t get_kmem_stats(zx_info_kmem_stats_t* kmem_stats) {
  zx::resource root_resource;
  zx_status_t ret = get_root_resource(&root_resource);
  if (ret != ZX_OK) {
    return ret;
  }

  zx_status_t err = zx_object_get_info(root_resource.get(), ZX_INFO_KMEM_STATS, kmem_stats,
                                       sizeof(*kmem_stats), nullptr, nullptr);
  if (err != ZX_OK) {
    fprintf(stderr, "ZX_INFO_KMEM_STATS returns %d (%s)\n", err, zx_status_get_string(err));
    return err;
  }

  return ZX_OK;
}

void print_help(char** argv, FILE* f) {
  fprintf(f, "Usage: %s [options]\n", argv[0]);
  fprintf(f, "options:\n");
  fprintf(f, "\t-h:                   This help\n");
  fprintf(f, "\t-t [time in seconds]: stop all tests after the time has elapsed\n");
  fprintf(f, "\t-v:                   verbose, status output\n");
}

}  // namespace

int main(int argc, char** argv) {
  zx_status_t status;

  bool verbose = false;
  zx::duration run_duration = zx::duration::infinite();

  int c;
  while ((c = getopt(argc, argv, "ht:v")) > 0) {
    switch (c) {
      case 'h':
        print_help(argv, stdout);
        return 0;
      case 't': {
        long t = atol(optarg);
        if (t <= 0) {
          fprintf(stderr, "bad time argument\n");
          print_help(argv, stderr);
          return 1;
        }
        run_duration = zx::sec(t);
        break;
      }
      case 'v':
        verbose = true;
        break;
      default:
        fprintf(stderr, "Unknown option\n");
        print_help(argv, stderr);
        return 1;
    }
  }

  // read some system stats for each test to use
  zx_info_kmem_stats_t kmem_stats;
  status = get_kmem_stats(&kmem_stats);
  if (status != ZX_OK) {
    fprintf(stderr, "error reading kmem stats\n");
    return 1;
  }

  if (run_duration != zx::duration::infinite()) {
    printf("Running stress tests for %" PRIu64 " seconds\n", run_duration.to_secs());
  } else {
    printf("Running stress tests continually\n");
  }

  // initialize all the tests
  for (auto& test : StressTest::tests()) {
    printf("Initializing %s test\n", test->name());
    status = test->Init(verbose, kmem_stats);
    if (status != ZX_OK) {
      fprintf(stderr, "error initializing test\n");
      return 1;
    }
  }

  // start all of them
  for (auto& test : StressTest::tests()) {
    printf("Starting %s test\n", test->name());
    status = test->Start();
    if (status != ZX_OK) {
      fprintf(stderr, "error initializing test\n");
      return 1;
    }
  }

  // set stdin to non blocking
  fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);

  zx::time start_time = zx::clock::get_monotonic();
  bool stop = false;
  for (;;) {
    // look for ctrl-c for terminals that do not support it
    char c;
    while (read(STDIN_FILENO, &c, 1) > 0) {
      if (c == 0x3) {
        stop = true;
        break;
      }
    }
    if (stop) {
      break;
    }

    // wait for a second to try again
    zx::nanosleep(zx::deadline_after(zx::sec(1)));

    if (run_duration != zx::duration::infinite()) {
      zx::time now = zx::clock::get_monotonic();
      if (now - start_time >= run_duration) {
        break;
      }
    }
  }

  // shut them down
  for (auto& test : StressTest::tests()) {
    printf("Stopping %s test\n", test->name());
    status = test->Stop();
    if (status != ZX_OK) {
      fprintf(stderr, "error stopping test\n");
      return 1;
    }
  }

  return 0;
}
