#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#ifdef __cplusplus
#define __STDC_FORMAT_MACROS
#endif

#include "experiments.h"

#include <inttypes.h>

#include <sstream>
#include <string>

#include "utils.h"

using namespace libexperiments_utils;  // NOLINT

Experiments *experiments = NULL;

int DefaultExperimentsRegisterFunc(const char *name) {
  std::vector<std::string> cmd({"register_experiment", name});
  std::ostringstream out, err;
  int64_t timeout_usec = secs_to_usecs(5);
  int status;
  int ret = run_cmd(cmd, "", &status, &out, &err, timeout_usec);
  if (ret < 0 || status != 0) {
    log("experiments:Error-Cannot register '%s', ret:%d status:%d stdout:%s "
        "stderr:%s", name, ret, status, out.str().c_str(),
        err.str().c_str());
    return 0;  // boolean false
  }
  return 1;  // boolean true
}

int DummyExperimentsRegisterFunc(const char *name) {
  return 1;  // boolean true
}

bool Experiments::Initialize(
    const std::string &config_dir, int64_t min_time_between_refresh_usec,
    experiments_register_func_t register_func,
    const std::vector<std::string> &names_to_register) {
  log("experiments:initializing - config_dir:%s min_time_between_refresh:%"
      PRId64 " us", config_dir.c_str(), min_time_between_refresh_usec);

  std::lock_guard<std::mutex> lock_guard(lock_);

  if (register_func == NULL) {
    log("experiments:Error-register_func is NULL");
    return false;
  }

  if (!directory_exists(config_dir.c_str())) {
    log("experiments:Error-config_dir '%s' does not exist", config_dir.c_str());
    return false;
  }

  if (min_time_between_refresh_usec < 0)
    min_time_between_refresh_usec = 0;

  config_dir_ = config_dir;
  register_func_ = register_func;
  min_time_between_refresh_usec_ = min_time_between_refresh_usec;

  initialized_ = true;  // initialization part succeeded at this point

  // register any provided experiments
  if (!names_to_register.empty()) {
    if (!Register_Locked(names_to_register))
      return false;
  }

  return true;
}

bool Experiments::Register(const std::vector<std::string> &names) {
  if (!IsInitialized()) {
    log("experiments:Cannot register, not initialized!");
    return false;
  }
  return Register_Unlocked(names);
}

bool Experiments::Register_Unlocked(const std::vector<std::string> &names) {
  std::lock_guard<std::mutex> lock_guard(lock_);
  return Register_Locked(names);
}

bool Experiments::Register_Locked(const std::vector<std::string> &names) {
  for (const auto &name : names) {
    if (IsInRegisteredList(name)) {
      log("experiments:'%s' already registered", name.c_str());
      continue;
    }

    // call external register function
    if (!register_func_(name.c_str()))
      return false;  // no reason to continue

    registered_experiments_.insert(name);
    log("experiments:Registered '%s'", name.c_str());

    // check if experiment is active
    std::string file_active = config_dir_ + "/" + name + ".active";
    if (file_exists(file_active.c_str())) {
      enabled_experiments_.insert(name);
      log("experiments:'%s' is now enabled", name.c_str());
    }
  }
  return true;
}

bool Experiments::IsRegistered(const std::string &name) {
  std::lock_guard<std::mutex> lock_guard(lock_);
  return IsInRegisteredList(name);
}

bool Experiments::IsEnabled(const std::string &name) {
  if (!IsInitialized())
    return false;  // silent return to avoid log flooding

  std::lock_guard<std::mutex> lock_guard(lock_);

  if (us_elapse(last_time_refreshed_usec_) >= min_time_between_refresh_usec_) {
    Refresh();
  }

  return IsInEnabledList(name);
}

void Experiments::Refresh() {
  for (const auto &name : registered_experiments_)
    UpdateState(name);
  last_time_refreshed_usec_ = us_elapse(0);
}

void Experiments::UpdateState(const std::string &name) {
  if (!IsInRegisteredList(name)) {
    log("experiments:'%s' not registered", name.c_str());
    return;
  }

  std::string experiments_path = config_dir_ + "/" + name;

  if (IsInEnabledList(name)) {
    // currently enabled, check if it was set to ".unrequested"
    std::string file_unrequested = experiments_path + ".unrequested";
    if (file_exists(file_unrequested.c_str())) {
      // deactivate experiment
      std::string file_active = experiments_path + ".active";
      rm_file(file_active.c_str());
      rm_file(file_unrequested.c_str());
      enabled_experiments_.erase(name);
      log("experiments:'%s' is now disabled", name.c_str());
    }
  } else {
    // currently not enabled, check if it is requested
    std::string file_requested = experiments_path + ".requested";
    if (file_exists(file_requested.c_str())) {
      // activate experiment
      std::string file_active = experiments_path + ".active";
      mv_file(file_requested.c_str(), file_active.c_str());
      enabled_experiments_.insert(name);
      log("experiments:'%s' is now enabled", name.c_str());
    }
  }
}


// API for C programs
int experiments_initialize(const char *config_dir,
                           int64_t min_time_between_refresh_usec,
                           experiments_register_func_t register_func) {
  if (register_func == NULL)
    register_func = DefaultExperimentsRegisterFunc;

  experiments = new Experiments();
  return experiments->Initialize(config_dir, min_time_between_refresh_usec,
                                 register_func, {});
}

int experiments_is_initialized() {
  return experiments ? experiments->IsInitialized() : false;
}

int experiments_register(const char *name) {
  return experiments ? experiments->Register(name) : false;
}

int experiments_is_registered(const char *name) {
  return experiments ? experiments->IsRegistered(name) : false;
}

int experiments_get_num_of_registered_experiments() {
  return experiments ? experiments->GetNumOfRegisteredExperiments() : 0;
}

int experiments_is_enabled(const char *name) {
  return experiments ? experiments->IsEnabled(name) : false;
}
