// 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/memory/monitor/high_water.h"

#include <lib/async/dispatcher.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/status.h>

#include <fstream>

#include <src/lib/files/file.h>
#include <src/lib/files/path.h>

#include "src/developer/memory/metrics/digest.h"
#include "src/developer/memory/metrics/printer.h"

namespace monitor {

using namespace memory;

static const char kLatest[] = "latest.txt";
static const char kPrevious[] = "previous.txt";
static const char kLatestDigest[] = "latest_digest.txt";
static const char kPreviousDigest[] = "previous_digest.txt";

HighWater::HighWater(const std::string& dir, zx::duration poll_frequency,
                     uint64_t high_water_threshold, async_dispatcher_t* dispatcher,
                     CaptureFn capture_cb)
    : dir_(dir),
      watcher_(poll_frequency, high_water_threshold, dispatcher, std::move(capture_cb),
               [this](const Capture& c) {
                 RecordHighWater(c);
                 RecordHighWaterDigest(c);
               }),
      namer_(Summary::kNameMatches) {
  // Ok to ignore result. last might not exist.
  remove(files::JoinPath(dir_, kPrevious).c_str());
  remove(files::JoinPath(dir_, kPreviousDigest).c_str());
  // Ok to ignore this too. Latest might not exist.
  rename(files::JoinPath(dir_, kLatest).c_str(), files::JoinPath(dir_, kPrevious).c_str());
  rename(files::JoinPath(dir_, kLatestDigest).c_str(),
         files::JoinPath(dir_, kPreviousDigest).c_str());
}

void HighWater::RecordHighWater(const Capture& capture) {
  Summary s(capture, &namer_);
  std::ofstream out;
  out.open(files::JoinPath(dir_, kLatest));
  Printer p(out);
  p.PrintSummary(s, VMO, memory::SORTED);
  out.close();
}

void HighWater::RecordHighWaterDigest(const Capture& capture) {
  Digest d(capture, &digester_);
  std::ofstream out;
  out.open(files::JoinPath(dir_, kLatestDigest));
  Printer p(out);
  p.PrintDigest(d);
  out.close();
}

std::string HighWater::GetHighWater() const { return GetFile(kLatest); }
std::string HighWater::GetPreviousHighWater() const { return GetFile(kPrevious); }
std::string HighWater::GetHighWaterDigest() const { return GetFile(kLatestDigest); }
std::string HighWater::GetPreviousHighWaterDigest() const { return GetFile(kPreviousDigest); }

std::string HighWater::GetFile(const char* filename) const {
  std::string file;
  if (files::ReadFileToString(files::JoinPath(dir_, filename), &file)) {
    return file;
  }
  return "";
}

}  // namespace monitor
