// 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/metrics/tests/test_utils.h"

#include <gtest/gtest.h>

namespace memory {

const zx_handle_t TestUtils::kRootHandle = 1;
const zx_handle_t TestUtils::kSelfHandle = 2;
const zx_koid_t TestUtils::kSelfKoid = 3;

class MockOS : public OS {
 public:
  MockOS(OsResponses responses)
      : responses_(responses),
        i_get_processes_(0),
        i_get_property_(0),
        i_get_info_(0),
        clock_(0) {}

 private:
  zx_status_t GetRootResource(zx_handle_t* root_resource) override {
    *root_resource = TestUtils::kRootHandle;
    return ZX_OK;
  }

  zx_handle_t ProcessSelf() override {
    return TestUtils::kSelfHandle;
  }

  zx_time_t GetMonotonic() override {
    return clock_++;
  }

  zx_status_t GetProcesses(
      fit::function<zx_status_t(int, zx_handle_t, zx_koid_t, zx_koid_t)> cb)
      override {
    auto const& r = responses_.get_processes.at(i_get_processes_++);
    for (auto const& c : r.callbacks) {
      auto ret = cb(c.depth, c.handle, c.koid, c.parent_koid);
      if (ret != ZX_OK) {
        return ret;
      }
    }
    return r.ret;
  }

  zx_status_t GetProperty(
      zx_handle_t handle, uint32_t property, void* value, size_t name_len)
     override {
    auto const& r = responses_.get_property.at(i_get_property_++);
    EXPECT_EQ(r.handle, handle);
    EXPECT_EQ(r.property, property);
    auto len = std::min(name_len, r.value_len);
    memcpy(value, r.value, len);
    return r.ret;
  }

  zx_status_t GetInfo(
      zx_handle_t handle,
      uint32_t topic,
      void* buffer,
      size_t buffer_size,
      size_t* actual,
      size_t* avail) override {
    auto const& r = responses_.get_info.at(i_get_info_++);
    EXPECT_EQ(r.handle, handle);
    EXPECT_EQ(r.topic, topic);
    size_t num_copied = 0;
    if (buffer != nullptr) {
      num_copied = std::min(r.value_count, buffer_size / r.value_size);
      memcpy(buffer, r.values, num_copied * r.value_size);
    }
    if (actual != nullptr) {
      *actual = num_copied;
    }
    if (avail != nullptr) {
      if (num_copied < r.value_count) {
        *avail = r.value_count - num_copied;
      } else {
        *avail = 0;
      }
    }
    return r.ret;
  }

  OsResponses responses_;
  uint32_t i_get_processes_, i_get_property_, i_get_info_;
  zx_time_t clock_;
};

// static.
void TestUtils::CreateCapture(memory::Capture& capture,
                              const CaptureTemplate& t) {
  capture.time_ = t.time;
  capture.kmem_= t.kmem;
  for (auto vmo : t.vmos) {
    capture.koid_to_vmo_.emplace(vmo.koid, vmo);
  }
  for (auto process : t.processes) {
    capture.koid_to_process_.emplace(process.koid, process);
  }
}

// static.
std::vector<ProcessSummary> TestUtils::GetProcessSummaries(
    const Summary& summary) {
  std::vector<ProcessSummary> summaries = summary.process_summaries();
  sort(summaries.begin(), summaries.end(),
       [](ProcessSummary a, ProcessSummary b) { return a.koid() < b.koid(); } );
  return summaries;
}

zx_status_t TestUtils::GetCapture(
      Capture& capture, CaptureLevel level, const OsResponses& r) {
  MockOS os(r);
  CaptureState state;
  zx_status_t ret = Capture::GetCaptureState(state, os);
  EXPECT_EQ(ZX_OK, ret);
  return Capture::GetCapture(capture, state, level, os);
}

}  // namespace memory
