// Copyright 2019 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 "src/developer/forensics/utils/utc_time_provider.h"

#include <lib/fit/function.h>

#include <optional>

#include "src/developer/forensics/utils/time.h"
#include "src/lib/files/file.h"

namespace forensics {

UtcTimeProvider::UtcTimeProvider(UtcClockReadyWatcherBase* utc_clock_ready_watcher,
                                 timekeeper::Clock* clock)
    : UtcTimeProvider(utc_clock_ready_watcher, clock, std::nullopt) {}

UtcTimeProvider::UtcTimeProvider(UtcClockReadyWatcherBase* utc_clock_ready_watcher,
                                 timekeeper::Clock* clock,
                                 PreviousBootFile utc_monotonic_difference_file)
    : UtcTimeProvider(utc_clock_ready_watcher, clock,
                      std::optional(utc_monotonic_difference_file)) {}

UtcTimeProvider::UtcTimeProvider(UtcClockReadyWatcherBase* utc_clock_ready_watcher,
                                 timekeeper::Clock* clock,
                                 std::optional<PreviousBootFile> utc_monotonic_difference_file)
    : clock_(clock),
      utc_monotonic_difference_file_(std::move(utc_monotonic_difference_file)),
      previous_boot_utc_monotonic_difference_(std::nullopt),
      utc_clock_ready_watcher_(utc_clock_ready_watcher) {
  utc_clock_ready_watcher->OnClockReady(
      fit::bind_member<&UtcTimeProvider::OnClockLoggingQuality>(this));

  if (!utc_monotonic_difference_file_.has_value()) {
    return;
  }

  std::string buf;
  if (!files::ReadFileToString(utc_monotonic_difference_file_.value().PreviousBootPath(), &buf)) {
    return;
  }

  previous_boot_utc_monotonic_difference_ =
      zx::duration(strtoll(buf.c_str(), nullptr, /*base*/ 10));
}

std::optional<timekeeper::time_utc> UtcTimeProvider::CurrentTime() const {
  if (!utc_clock_ready_watcher_->IsUtcClockReady()) {
    return std::nullopt;
  }

  return CurrentUtcTimeRaw(clock_);
}

std::optional<zx::duration> UtcTimeProvider::CurrentUtcMonotonicDifference() const {
  if (!utc_clock_ready_watcher_->IsUtcClockReady()) {
    return std::nullopt;
  }

  const timekeeper::time_utc current_utc_time = CurrentUtcTimeRaw(clock_);
  const zx::duration utc_monotonic_difference(current_utc_time.get() - clock_->Now().get());
  if (utc_monotonic_difference_file_.has_value()) {
    // Write the most recent UTC-monotonic difference in case either clock has been adjusted.
    files::WriteFile(utc_monotonic_difference_file_.value().CurrentBootPath(),
                     std::to_string(utc_monotonic_difference.get()));
  }
  return utc_monotonic_difference;
}

std::optional<zx::duration> UtcTimeProvider::PreviousBootUtcMonotonicDifference() const {
  return previous_boot_utc_monotonic_difference_;
}

void UtcTimeProvider::OnClockLoggingQuality() {
  // Write the current difference between the UTC and monotonic clocks.
  if (utc_monotonic_difference_file_.has_value()) {
    const timekeeper::time_utc current_utc_time = CurrentUtcTimeRaw(clock_);
    const zx::duration utc_monotonic_difference(current_utc_time.get() - clock_->Now().get());
    files::WriteFile(utc_monotonic_difference_file_.value().CurrentBootPath(),
                     std::to_string(utc_monotonic_difference.get()));
  }
}

}  // namespace forensics
