// Copyright 2017 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 "config/analyzer_config_manager.h"

#include <errno.h>
#include <spawn.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fstream>
#include <memory>
#include <mutex>
#include <string>
#include <utility>

#include "config/analyzer_config.h"
#include "config/cobalt_config.pb.h"
#include "gflags/gflags.h"
#include "glog/logging.h"
#include "util/log_based_metrics.h"

namespace cobalt {
namespace config {

DEFINE_string(cobalt_config_proto_path, "",
              "Location on disk of the serialized CobaltConfig proto from "
              "which the Report Master's configuration is to be read.");
DEFINE_string(config_update_repository_url, "",
              "URL to a git repository containing a cobalt configuration in "
              "its master branch. If this flag is set, the configuration of "
              "report master will be updated by pulling from the specified "
              "repository before scheduled reports are run. "
              "(e.g. \"https://cobalt-analytics.googlesource.com/config/\")");
DEFINE_string(config_parser_bin_path, "/usr/local/bin/config_parser",
              "Location on disk of the configuration parser.");

// Stackdriver metric constants
namespace {
const char kUpdateFailure[] = "analyzer-config-manager-update-failure";
const char kReadConfigFromCobaltConfigFileFailure[] =
    "analyzer-config-manager-read-config-from-cobalt-config-file-failure";
}  // namespace

AnalyzerConfigManager::AnalyzerConfigManager(
    std::shared_ptr<AnalyzerConfig> config,
    std::string cobalt_config_proto_path,
    std::string config_update_repository_url,
    std::string config_parser_bin_path)
    : cobalt_config_proto_path_(cobalt_config_proto_path),
      update_repository_path_(config_update_repository_url),
      config_parser_bin_path_(config_parser_bin_path) {
  ptr_ = config;
}

AnalyzerConfigManager::AnalyzerConfigManager(
    std::shared_ptr<AnalyzerConfig> config) {
  ptr_ = config;
}

std::shared_ptr<AnalyzerConfig> AnalyzerConfigManager::GetCurrent() {
  std::lock_guard<std::mutex> lock(m_);
  return ptr_;
}

std::shared_ptr<AnalyzerConfigManager>
AnalyzerConfigManager::CreateFromFlagsOrDie() {
  if (FLAGS_cobalt_config_proto_path.empty()) {
    auto config = AnalyzerConfig::CreateFromFlagsOrDie();
    return std::shared_ptr<AnalyzerConfigManager>(
        new AnalyzerConfigManager(std::move(config)));
  }

  // If a file containing a serialized CobaltConfig is specified, we load the
  // initial configuration from that file.
  auto config =
      ReadConfigFromSerializedCobaltConfigFile(FLAGS_cobalt_config_proto_path);
  if (!config) {
    LOG(FATAL) << "Could not load the initial configuration.";
  }
  LOG(INFO) << "Initial configuration loaded.";

  auto manager =
      std::shared_ptr<AnalyzerConfigManager>(new AnalyzerConfigManager(
          std::move(config), FLAGS_cobalt_config_proto_path,
          FLAGS_config_update_repository_url, FLAGS_config_parser_bin_path));
  manager->Update(120);
  return manager;
}

bool AnalyzerConfigManager::Update(unsigned int timeout_seconds) {
  // If no repository to get updates from was specified, skip the update.
  if (update_repository_path_.empty()) {
    return false;
  }

  LOG(INFO) << "Updating configuration from " << update_repository_path_;

  std::string timeout_seconds_str = std::to_string(timeout_seconds);
  const char* argv[] = {
      config_parser_bin_path_.c_str(),   "-repo_url",
      update_repository_path_.c_str(),   "-output_file",
      cobalt_config_proto_path_.c_str(), "-git_timeout",
      timeout_seconds_str.c_str(),       nullptr,
  };
  pid_t pid;
  posix_spawnattr_t spawnattr;
  posix_spawnattr_init(&spawnattr);

  errno = 0;
  // The variable "environ" is the current environment found in unistd.h.
  int status = posix_spawn(&pid, config_parser_bin_path_.c_str(), nullptr,
                           &spawnattr, const_cast<char* const*>(argv), environ);

  if (0 != status) {
    LOG_STACKDRIVER_COUNT_METRIC(ERROR, kUpdateFailure)
        << "Error spawning config_parser at " << config_parser_bin_path_
        << " with error: " << strerror(errno);
    return false;
  }
  LOG(INFO) << "Spawned " << config_parser_bin_path_;

  // Catch state changes of config_parser process until it terminates.
  errno = 0;
  if (waitpid(pid, &status, WUNTRACED) != pid) {
    LOG_STACKDRIVER_COUNT_METRIC(ERROR, kUpdateFailure)
        << "Error waiting for config_parser: " << strerror(errno);
    return false;
  }

  if (!WIFEXITED(status) || 0 != WEXITSTATUS(status)) {
    if (WIFSIGNALED(status)) {
      LOG_STACKDRIVER_COUNT_METRIC(ERROR, kUpdateFailure)
          << "config_parser terminated by signal " << WTERMSIG(status);
      return false;
    } else if (WIFEXITED(status)) {
      LOG_STACKDRIVER_COUNT_METRIC(ERROR, kUpdateFailure)
          << "config_parser exited with signal " << WEXITSTATUS(status);
      return false;
    } else if (WIFSTOPPED(status)) {
      LOG_STACKDRIVER_COUNT_METRIC(ERROR, kUpdateFailure)
          << "config_parser was stopped by signal " << WSTOPSIG(status);
      return false;
    } else {
      LOG_STACKDRIVER_COUNT_METRIC(ERROR, kUpdateFailure)
          << "Error while waiting for config_parser.";
      return false;
    }
  }
  LOG(INFO) << "Done getting updated configuration from "
            << update_repository_path_;

  auto config =
      ReadConfigFromSerializedCobaltConfigFile(cobalt_config_proto_path_);
  std::lock_guard<std::mutex> lock(m_);
  ptr_.reset(config.release());

  LOG(INFO) << "Configuration updated.";
  return true;
}

std::unique_ptr<AnalyzerConfig>
AnalyzerConfigManager::ReadConfigFromSerializedCobaltConfigFile(
    std::string config_path) {
  std::ifstream config_file_stream;
  config_file_stream.open(config_path);
  if (!config_file_stream) {
    LOG_STACKDRIVER_COUNT_METRIC(ERROR, kReadConfigFromCobaltConfigFileFailure)
        << "Could not open config proto: " << config_path;
    return nullptr;
  }

  CobaltConfig cobalt_config;
  if (!cobalt_config.ParseFromIstream(&config_file_stream)) {
    LOG_STACKDRIVER_COUNT_METRIC(ERROR, kReadConfigFromCobaltConfigFileFailure)
        << "Could not parse config proto: " << config_path;
    return nullptr;
  }

  auto config = AnalyzerConfig::CreateFromCobaltConfigProto(&cobalt_config);
  if (!config) {
    LOG_STACKDRIVER_COUNT_METRIC(ERROR, kReadConfigFromCobaltConfigFileFailure)
        << "Error creating AnalyzerConfig: " << config_path;
    return nullptr;
  }

  return config;
}

}  // namespace config
}  // namespace cobalt
