// 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 <fcntl.h>
#include <fuchsia/cobalt/cpp/fidl.h>
#include <fuchsia/scheduler/cpp/fidl.h>
#include <fuchsia/sysinfo/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/cpp/task.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/trace-provider/provider.h>
#include <lib/zx/channel.h>
#include <lib/zx/clock.h>
#include <stdlib.h>
#include <zircon/boot/image.h>
#include <zircon/types.h>
#include <zircon/utc.h>

#include <chrono>
#include <fstream>
#include <memory>
#include <string>
#include <thread>
#include <utility>

#include "src/cobalt/bin/app/cobalt_app.h"
#include "src/lib/files/file.h"
#include "src/lib/fxl/command_line.h"
#include "src/lib/fxl/log_settings_command_line.h"
#include "src/lib/fxl/strings/join_strings.h"
#include "src/lib/fxl/strings/split_string.h"
#include "src/public/cobalt_config.h"

// Command-line flags

// Used to override kScheduleIntervalDefault;
constexpr std::string_view kScheduleIntervalSecondsFlagName = "schedule_interval_seconds";

constexpr std::string_view kInitialIntervalSecondsFlagName = "initial_interval_seconds";

// Used to override kMinIntervalDefault;
constexpr std::string_view kMinIntervalSecondsFlagName = "min_interval_seconds";

// Used to override kUploadJitterDefault;
constexpr std::string_view kUploadJitterFlagName = "upload_jitter";

// Used to override kEventAggregatorBackfillDaysDefault
constexpr std::string_view kEventAggregatorBackfillDaysFlagName = "event_aggregator_backfill_days";

// Used to override kStartEventAggregatorWorkerDefault
constexpr std::string_view kStartEventAggregatorWorkerFlagName = "start_event_aggregator_worker";

constexpr std::string_view kUseMemoryObservationStore = "use_memory_observation_store";

constexpr std::string_view kMaxBytesTotalFlagName = "max_bytes_per_observation_store";

constexpr std::string_view kTestOnlyFakeClockFlagName = "test_only_use_fake_clock";

// We want to only upload every hour. This is the interval that will be
// approached by the uploader.
const std::chrono::hours kScheduleIntervalDefault(1);

// We start uploading every minute and exponentially back off until we reach 1
// hour.
const std::chrono::minutes kInitialIntervalDefault(1);

// We send Observations to the Shuffler more frequently than kScheduleInterval
// under some circumstances, namely, if there is memory pressure or if we
// are explicitly asked to do so via the RequestSendSoon() method. This value
// is a safety parameter. We do not make two attempts within a period of this
// specified length.
const std::chrono::seconds kMinIntervalDefault(10);

// Offset uploads by at most 20% of current interval.
float kUploadJitterDefault(.2);

// The EventAggregator looks back 2 days, in addition to the previous day, to
// make sure that all locally aggregated observations have been generated.
const size_t kEventAggregatorBackfillDaysDefault(2);

// We normally start the EventAggregator's worker thread after constructing the
// EventAggregator.
constexpr bool kStartEventAggregatorWorkerDefault(true);

// ReadBoardName returns the board name of the currently running device.
//
// At the time of this writing, this will either be 'pc' for x86 devices, or an
// appropriate board name for ARM devices (sherlock, qemu).
//
// This uses the fuchsia-sysinfo fidl service to read the board_name field out
// of the ZBI. This string will never exceed a length of 32.
//
// If the reading of the board name fails for any reason, this will return "".
std::string ReadBoardName(const std::shared_ptr<sys::ServiceDirectory>& services) {
  fuchsia::sysinfo::SysInfoSyncPtr sysinfo;
  services->Connect<fuchsia::sysinfo::SysInfo>(sysinfo.NewRequest());

  // Read the board name out of the ZBI.
  zx_status_t status;
  fidl::StringPtr board_name;
  zx_status_t fidl_status = sysinfo->GetBoardName(&status, &board_name);
  if (fidl_status != ZX_OK || status != ZX_OK) {
    return "";
  }

  return board_name.value();
}

std::string ReadBuildInfo(std::string value) {
  std::ifstream file("/config/build-info/" + value);
  if (file.is_open()) {
    std::stringstream buffer;
    buffer << file.rdbuf();
    auto val = buffer.str();
    if (val == "") {
      return "<" + value + " not specified>";
    }
    return val;
  } else {
    return "<" + value + " read failed>";
  }
}

// Replaces the UTC clock installed in the process' namespace with a fake one
// that is always started. This is intended to simulate a synchronized clock in
// test environments without network and should not be used outside of tests.
void ReplaceRuntimeClock() {
  zx::clock current_clock(zx_utc_reference_get());
  zx::time start_time;
  current_clock.read(start_time.get_address());

  zx::clock replacement;
  zx_clock_create_args_v1_t clock_args{.backstop_time = start_time.get()};
  zx::clock::create(0u, &clock_args, &replacement);
  zx::clock::update_args update_args;
  update_args.set_value(start_time);
  replacement.update(update_args);
  zx_utc_reference_swap(replacement.release(), current_clock.reset_and_get_address());
}

int main(int argc, const char** argv) {
  // Parse the flags.
  const auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
  fxl::SetLogSettingsFromCommandLine(command_line, {"cobalt", "fidl_service"});

  // Parse the schedule_interval_seconds flag.
  std::chrono::seconds schedule_interval =
      std::chrono::duration_cast<std::chrono::seconds>(kScheduleIntervalDefault);
  std::chrono::seconds initial_interval =
      std::chrono::duration_cast<std::chrono::seconds>(kInitialIntervalDefault);
  std::string flag_value;
  if (command_line.GetOptionValue(kScheduleIntervalSecondsFlagName, &flag_value)) {
    int num_seconds = std::stoi(flag_value);
    if (num_seconds > 0) {
      schedule_interval = std::chrono::seconds(num_seconds);
      // Set initial_interval, it can still be overridden by a flag.
      initial_interval = std::chrono::seconds(num_seconds);
    }
  }

  // Parse the initial_interval_seconds flag.
  flag_value.clear();
  if (command_line.GetOptionValue(kInitialIntervalSecondsFlagName, &flag_value)) {
    int num_seconds = std::stoi(flag_value);
    if (num_seconds > 0) {
      initial_interval = std::chrono::seconds(num_seconds);
    }
  }

  // Parse the min_interval_seconds flag.
  std::chrono::seconds min_interval =
      std::chrono::duration_cast<std::chrono::seconds>(kMinIntervalDefault);
  flag_value.clear();
  if (command_line.GetOptionValue(kMinIntervalSecondsFlagName, &flag_value)) {
    int num_seconds = std::stoi(flag_value);
    // We allow min_interval = 0.
    if (num_seconds >= 0) {
      min_interval = std::chrono::seconds(num_seconds);
    }
  }

  // Parse the upload_jitter flag.
  float upload_jitter = kUploadJitterDefault;
  flag_value.clear();
  if (command_line.GetOptionValue(kUploadJitterFlagName, &flag_value)) {
    float jitter_percentage = std::stof(flag_value);
    // We allow 0 <= jitter < 1.
    if (jitter_percentage >= 0 && jitter_percentage < 1) {
      upload_jitter = jitter_percentage;
    }
  }

  // Parse the event_aggregator_backfill_days flag.
  size_t event_aggregator_backfill_days = kEventAggregatorBackfillDaysDefault;
  flag_value.clear();
  if (command_line.GetOptionValue(kEventAggregatorBackfillDaysFlagName, &flag_value)) {
    int num_days = std::stoi(flag_value);
    // We allow num_days = 0.
    if (num_days >= 0) {
      event_aggregator_backfill_days = num_days;
    }
  }

  // Parse the start_event_aggregator_worker flag.
  bool start_event_aggregator_worker = kStartEventAggregatorWorkerDefault;
  flag_value.clear();
  if (command_line.GetOptionValue(kStartEventAggregatorWorkerFlagName, &flag_value)) {
    if (flag_value == "true") {
      start_event_aggregator_worker = true;
    } else if (flag_value == "false") {
      start_event_aggregator_worker = false;
    }
  }

  bool use_memory_observation_store = command_line.HasOption(kUseMemoryObservationStore);

  // Parse the max_bytes_per_observation_store
  size_t max_bytes_per_observation_store = 1024 * 1024;  // 1 MiB
  flag_value.clear();
  if (command_line.GetOptionValue(kMaxBytesTotalFlagName, &flag_value)) {
    int num_bytes = std::stoi(flag_value);
    if (num_bytes > 0) {
      max_bytes_per_observation_store = num_bytes;
    }
  }

  bool use_fake_clock = command_line.HasOption(kTestOnlyFakeClockFlagName);

  FX_LOGS(INFO) << "Cobalt is starting with the following parameters: "
                << "schedule_interval=" << schedule_interval.count()
                << " seconds, min_interval=" << min_interval.count()
                << " seconds, initial_interval=" << initial_interval.count()
                << " seconds, upload_jitter=" << (upload_jitter * 100) << "%"
                << ", max_bytes_per_observation_store=" << max_bytes_per_observation_store
                << ", event_aggregator_backfill_days=" << event_aggregator_backfill_days
                << ", start_event_aggregator_worker=" << start_event_aggregator_worker
                << ", test_only_use_fake_clock=" << use_fake_clock << ".";

  if (use_fake_clock) {
    FX_LOGS(WARNING) << "Using a fake clock. This should only be enabled in tests.";
    ReplaceRuntimeClock();
  }

  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);

  auto context = sys::ComponentContext::CreateAndServeOutgoingDirectory();

  // Lower the priority of the main thread.
  fuchsia::scheduler::ProfileProviderSyncPtr provider;
  context->svc()->Connect<fuchsia::scheduler::ProfileProvider>(provider.NewRequest());
  zx_status_t fidl_status;
  zx::profile profile;
  auto status =
      provider->GetProfile(0 /* LOWEST_PRIORITY */, "src/cobalt/bin/app", &fidl_status, &profile);
  if (status == ZX_OK) {
    FX_CHECK(fidl_status == ZX_OK) << "Recieved error while acquiring profile";
    FX_LOGS(INFO) << "Fetched profile!";
    status = zx_object_set_profile(zx_thread_self(), profile.get(), 0);
    FX_CHECK(status == ZX_OK) << "Unable to set current thread priority";
    FX_LOGS(INFO) << "Profile aplied to current thread";
  } else {
    // If we fail with ZX_ERR_PEER_CLOSED, then the ProfileProvider is down, and we should continue
    // anyway.
    FX_CHECK(status == ZX_ERR_PEER_CLOSED)
        << "Unable to connect to ProfileProvider, received unexpected error (" << status << ")";
    FX_LOGS(INFO) << "Unable to lower current thread provider. ProfileProvider is down.";
  }

  auto boardname = ReadBoardName(context->svc());
  trace::TraceProviderWithFdio trace_provider(loop.dispatcher(), "cobalt_fidl_provider");
  cobalt::UploadScheduleConfig upload_schedule = {
      .target_interval = schedule_interval,
      .min_interval = min_interval,
      .initial_interval = initial_interval,
      .jitter = upload_jitter,
  };
  cobalt::CobaltApp app = cobalt::CobaltApp::CreateCobaltApp(
      std::move(context), loop.dispatcher(), upload_schedule, event_aggregator_backfill_days,
      start_event_aggregator_worker, use_memory_observation_store, max_bytes_per_observation_store,
      ReadBuildInfo("product"), boardname, ReadBuildInfo("version"));
  loop.Run();
  return 0;
}
