// Copyright 2018 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 "system_load_heart_model.h"

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <limits>

#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>

#include <fuchsia/sysinfo/c/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <zircon/status.h>
#include <zircon/syscalls/object.h>

namespace bt_le_heart_rate {
namespace {

zx::handle GetRootResource() {
  const int fd = open("/dev/misc/sysinfo", O_RDWR);
  if (fd == 0)
    return {};

  zx::channel channel;
  zx_status_t status =
      fdio_get_service_handle(fd, channel.reset_and_get_address());
  if (status != ZX_OK)
    return {};

  zx_handle_t root_resource;
  zx_status_t fidl_status = fuchsia_sysinfo_DeviceGetRootResource(
      channel.get(), &status, &root_resource);
  if (fidl_status != ZX_OK || status != ZX_OK)
    return {};

  return zx::handle(root_resource);
}

size_t ReadCpuCount(const zx::handle& root_resource) {
  size_t actual, available;

  zx_status_t err = root_resource.get_info(ZX_INFO_CPU_STATS, nullptr, 0,
                                           &actual, &available);

  if (err != ZX_OK)
    return 0;

  return available;
}

}  // namespace

SystemLoadHeartModel::SystemLoadHeartModel()
    : root_resource_(GetRootResource()),
      cpu_stats_(ReadCpuCount(root_resource_)),
      last_cpu_stats_(cpu_stats_.size()),
      last_read_time_(zx::clock::get_monotonic()) {
  FXL_DCHECK(root_resource_);
  FXL_DCHECK(!cpu_stats_.empty());

  ReadCpuStats();
  last_cpu_stats_.swap(cpu_stats_);
}

bool SystemLoadHeartModel::ReadMeasurement(Measurement* measurement) {
  if (!ReadCpuStats())
    return false;

  const zx::time read_time = zx::clock::get_monotonic();
  zx::duration idle_sum;
  for (size_t i = 0; i < cpu_stats_.size(); i++) {
    idle_sum +=
        zx::duration(cpu_stats_[i].idle_time - last_cpu_stats_[i].idle_time);
    energy_counter_ +=
        cpu_stats_[i].context_switches - last_cpu_stats_[i].context_switches;
  }

  const zx::duration elapsed = read_time - last_read_time_;

  const auto idle_percent =
      (idle_sum.get() * 100) / (elapsed.get() * cpu_stats_.size());

  measurement->contact = true;
  measurement->rate = 100 - idle_percent;
  measurement->energy_expended = std::min<decltype(energy_counter_)>(
      energy_counter_, std::numeric_limits<int>::max());

  last_read_time_ = read_time;
  last_cpu_stats_.swap(cpu_stats_);

  return true;
}

bool SystemLoadHeartModel::ReadCpuStats() {
  size_t actual, available;

  zx_status_t err = root_resource_.get_info(
      ZX_INFO_CPU_STATS, &cpu_stats_[0],
      cpu_stats_.size() * sizeof(zx_info_cpu_stats), &actual, &available);

  return (err == ZX_OK && actual == available);
}

}  // namespace bt_le_heart_rate
