// 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 <cpuid.h>
#include <errno.h>
#include <fcntl.h>
#include <fidl/fuchsia.hardware.thermal/cpp/wire.h>
#include <fidl/fuchsia.kernel/cpp/wire.h>
#include <inttypes.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/fdio/watcher.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/trace-provider/provider.h>
#include <lib/trace/event.h>
#include <lib/zx/channel.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/system.h>

#include <future>

#include <fbl/unique_fd.h>

// degrees Celsius below threshold before we adjust PL value
constexpr float kCoolThresholdCelsius = 5.0f;

class PlatformConfiguration {
 public:
  static std::unique_ptr<PlatformConfiguration> Create(zx::resource);

  zx_status_t SetMinPL1() { return SetPL1Mw(pl1_min_mw_); }
  zx_status_t SetMaxPL1() { return SetPL1Mw(pl1_max_mw_); }

  bool IsAtMax() { return current_pl1_mw_ == pl1_max_mw_; }
  bool IsAtMin() { return current_pl1_mw_ == pl1_min_mw_; }

 private:
  PlatformConfiguration(uint32_t pl1_min_mw, uint32_t pl1_max_mw, zx::resource power_resource)
      : pl1_min_mw_(pl1_min_mw),
        pl1_max_mw_(pl1_max_mw),
        power_resource_(std::move(power_resource)) {}

  zx_status_t SetPL1Mw(uint32_t target_mw);

  const uint32_t pl1_min_mw_;
  const uint32_t pl1_max_mw_;
  const zx::resource power_resource_;

  static constexpr uint32_t kEvePL1MinMw = 2500;
  static constexpr uint32_t kEvePL1MaxMw = 7000;

  static constexpr uint32_t kAtlasPL1MinMw = 3000;
  static constexpr uint32_t kAtlasPL1MaxMw = 7000;

  uint32_t current_pl1_mw_;
};

zx::result<zx::resource> get_power_resource() {
  zx::result client_end = component::Connect<fuchsia_kernel::PowerResource>();
  if (client_end.is_error()) {
    FX_PLOGS(ERROR, client_end.status_value()) << "Failed to open fuchsia.kernel.PowerResource";
    return client_end.take_error();
  }
  fidl::WireSyncClient client{std::move(client_end.value())};
  fidl::WireResult result = client->Get();
  if (!result.ok()) {
    FX_PLOGS(ERROR, result.status()) << "FIDL error while trying to get power resource";
    return zx::error(result.status());
  }
  return zx::ok(std::move(result.value().resource));
}

std::unique_ptr<PlatformConfiguration> PlatformConfiguration::Create(zx::resource power_resource) {
  unsigned int a, b, c, d;
  unsigned int leaf_num = 0x80000002;
  char brand_string[50];
  memset(brand_string, 0, sizeof(brand_string));
  for (int i = 0; i < 3; i++) {
    if (!__get_cpuid(leaf_num + i, &a, &b, &c, &d)) {
      return nullptr;
    }
    memcpy(brand_string + (i * 16), &a, sizeof(uint32_t));
    memcpy(brand_string + (i * 16) + 4, &b, sizeof(uint32_t));
    memcpy(brand_string + (i * 16) + 8, &c, sizeof(uint32_t));
    memcpy(brand_string + (i * 16) + 12, &d, sizeof(uint32_t));
  }
  // Only run thermd for processors used in Pixelbooks. The PL1 min/max settings are specified by
  // the chipset.
  if (strstr(brand_string, "i5-7Y57") || strstr(brand_string, "i7-7Y75")) {
    return std::unique_ptr<PlatformConfiguration>(
        new PlatformConfiguration(kEvePL1MinMw, kEvePL1MaxMw, std::move(power_resource)));
  } else if (strstr(brand_string, "i5-8200Y") || strstr(brand_string, "i7-8500Y") ||
             strstr(brand_string, "m3-8100Y")) {
    return std::unique_ptr<PlatformConfiguration>(
        new PlatformConfiguration(kAtlasPL1MinMw, kAtlasPL1MaxMw, std::move(power_resource)));
  }
  return nullptr;
}

zx_status_t PlatformConfiguration::SetPL1Mw(uint32_t target_mw) {
  zx_system_powerctl_arg_t arg = {
      .x86_power_limit =
          {
              .power_limit = target_mw,
              .time_window = 0,
              .clamp = 1,
              .enable = 1,
          },
  };
  zx_status_t status =
      zx_system_powerctl(power_resource_.get(), ZX_SYSTEM_POWERCTL_X86_SET_PKG_PL1, &arg);
  if (status != ZX_OK) {
    FX_PLOGS(ERROR, status) << "Failed to set PL1 to " << target_mw;
    return status;
  }
  current_pl1_mw_ = target_mw;
  TRACE_COUNTER("thermal", "throttle", 0, "pl1", target_mw);
  return ZX_OK;
}

void start_trace() {
  // Create a message loop
  static async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  static trace::TraceProviderWithFdio trace_provider(loop.dispatcher());
  static bool started = false;
  if (!started) {
    loop.StartThread();
    started = true;
  }
}

// TODO(https://fxbug.dev/42059997): This code here needs an update, it's using some very old patterns.
zx_status_t RunThermd() {
  zx::result power_resource = get_power_resource();
  if (power_resource.is_error()) {
    FX_PLOGS(ERROR, power_resource.status_value()) << "Failed to get power resource";
    return power_resource.status_value();
  }

  auto config = PlatformConfiguration::Create(std::move(power_resource.value()));
  if (!config) {
    // If there is no platform configuration then we should warn since thermd should only be
    // included on devices where we expect it to run.
    FX_LOGS(WARNING) << "no platform configuration found";
    return ZX_ERR_NOT_FOUND;
  }

  FX_LOGS(INFO) << "started";

  start_trace();

  zx_nanosleep(zx_deadline_after(ZX_SEC(3)));

  fbl::unique_fd dirfd;
  if (dirfd.reset(open("/dev/class/thermal", O_DIRECTORY | O_RDONLY)) < 0) {
    FX_LOGS(ERROR) << "Failed to open /dev/class/thermal: " << strerror(errno);
    return ZX_ERR_IO;
  }

  std::optional<zx::result<fidl::ClientEnd<fuchsia_hardware_thermal::Device>>> device;
  if (zx_status_t status = fdio_watch_directory(
          dirfd.get(),
          [](int dirfd, int event, const char* name, void* cookie) {
            if (event != WATCH_EVENT_ADD_FILE) {
              return ZX_OK;
            }
            if (std::string_view{name} == ".") {
              return ZX_OK;
            }
            // first sensor is ambient sensor
            // TODO(https://fxbug.dev/42059997): come up with a way to detect this is the ambient sensor
            auto& device = *static_cast<
                std::optional<zx::result<fidl::ClientEnd<fuchsia_hardware_thermal::Device>>>*>(
                cookie);
            fdio_cpp::UnownedFdioCaller caller(dirfd);
            device.emplace(
                component::ConnectAt<fuchsia_hardware_thermal::Device>(caller.directory(), name));
            return ZX_ERR_STOP;
          },
          ZX_TIME_INFINITE, &device);
      status != ZX_ERR_STOP) {
    FX_PLOGS(ERROR, status) << "watcher terminating without finding sensors, terminating thermd...";
    return status;
  }

  if (!device.has_value()) {
    FX_LOGS(ERROR) << "watcher did not find sensors, terminating thermd...";
    return ZX_ERR_NOT_FOUND;
  }
  if (device.value().is_error()) {
    FX_PLOGS(ERROR, device.value().status_value()) << "failed to connect to sensor";
    return device.value().status_value();
  }
  fidl::WireSyncClient client{std::move(device.value().value())};

  float temp;
  {
    const fidl::WireResult result = client->GetTemperatureCelsius();
    if (!result.ok()) {
      FX_PLOGS(ERROR, result.status()) << "Failed to get temperature";
      return result.status();
    }
    const fidl::WireResponse response = result.value();
    if (zx_status_t status = response.status; status != ZX_OK) {
      FX_PLOGS(ERROR, status) << "Failed to get temperature";
      return status;
    }
    temp = response.temp;
    TRACE_COUNTER("thermal", "temp", 0, "ambient-c", temp);
  }
  fuchsia_hardware_thermal::wire::ThermalInfo info;
  {
    const fidl::WireResult result = client->GetInfo();
    if (!result.ok()) {
      FX_PLOGS(ERROR, result.status()) << "Failed to get info";
      return result.status();
    }
    const fidl::WireResponse response = result.value();
    if (zx_status_t status = response.status; status != ZX_OK) {
      FX_PLOGS(ERROR, status) << "Failed to get info";
      return status;
    }
    info = *response.info;
    TRACE_COUNTER("thermal", "trip-point", 0, "passive-c", info.passive_temp_celsius, "critical-c",
                  info.critical_temp_celsius);
    if (info.max_trip_count == 0) {
      FX_LOGS(ERROR) << "Trip points not supported, exiting";
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  zx::event h;
  {
    fidl::WireResult result = client->GetStateChangeEvent();
    if (!result.ok()) {
      FX_PLOGS(ERROR, result.status()) << "Failed to get state change event";
      return result.status();
    }
    auto& response = result.value();
    if (zx_status_t status = response.status; status != ZX_OK) {
      FX_PLOGS(ERROR, status) << "Failed to get state change event";
      return status;
    }
    h = std::move(response.handle);
  }
  // Set a trip point.
  {
    const fidl::WireResult result = client->SetTripCelsius(0, info.passive_temp_celsius);
    if (!result.ok()) {
      FX_PLOGS(ERROR, result.status()) << "Failed to set trip point";
      return result.status();
    }
    const auto& response = result.value();
    if (zx_status_t status = response.status; status != ZX_OK) {
      FX_PLOGS(ERROR, status) << "Failed to set trip point";
      return status;
    }
  }
  // Update info.
  {
    const fidl::WireResult result = client->GetInfo();
    if (!result.ok()) {
      FX_PLOGS(ERROR, result.status()) << "Failed to get info";
      return result.status();
    }
    const fidl::WireResponse response = result.value();
    if (zx_status_t status = response.status; status != ZX_OK) {
      FX_PLOGS(ERROR, status) << "Failed to get info";
      return status;
    }
    info = *response.info;
    TRACE_COUNTER("thermal", "trip-point", 0, "passive-c", info.passive_temp_celsius, "critical-c",
                  info.critical_temp_celsius, "active0-c", info.active_trip[0]);
  }

  // Set PL1 to the platform maximum.
  config->SetMaxPL1();

  for (;;) {
    zx_signals_t observed = 0;
    zx_status_t status = h.wait_one(ZX_USER_SIGNAL_0, zx::deadline_after(zx::sec(1)), &observed);
    if ((status != ZX_OK) && (status != ZX_ERR_TIMED_OUT)) {
      FX_PLOGS(ERROR, status) << "Failed to wait on event";
      return status;
    }
    if (observed & ZX_USER_SIGNAL_0) {
      const fidl::WireResult result = client->GetInfo();
      if (!result.ok()) {
        FX_PLOGS(ERROR, result.status()) << "Failed to get info";
        return result.status();
      }
      const fidl::WireResponse response = result.value();
      if (zx_status_t status = response.status; status != ZX_OK) {
        FX_PLOGS(ERROR, status) << "Failed to get info";
        return status;
      }
      info = *response.info;
      if (info.state) {
        // Decrease power limit
        config->SetMinPL1();

        const fidl::WireResult result = client->GetTemperatureCelsius();
        if (!result.ok()) {
          FX_PLOGS(ERROR, result.status()) << "Failed to get temperature";
          return result.status();
        }
        const fidl::WireResponse response = result.value();
        if (zx_status_t status = response.status; status != ZX_OK) {
          FX_PLOGS(ERROR, status) << "Failed to get temperature";
          return status;
        }
        temp = response.temp;
      } else {
        TRACE_COUNTER("thermal", "event", 0, "spurious", temp);
      }
    }
    if (status == ZX_ERR_TIMED_OUT) {
      const fidl::WireResult result = client->GetTemperatureCelsius();
      if (!result.ok()) {
        FX_PLOGS(ERROR, result.status()) << "Failed to get temperature";
        return result.status();
      }
      const fidl::WireResponse response = result.value();
      if (zx_status_t status = response.status; status != ZX_OK) {
        FX_PLOGS(ERROR, status) << "Failed to get temperature";
        return status;
      }
      temp = response.temp;
      TRACE_COUNTER("thermal", "temp", 0, "ambient-c", temp);

      // Increase power limit if the temperature dropped enough
      if (temp < info.active_trip[0] - kCoolThresholdCelsius && !config->IsAtMax()) {
        // Make sure the state is clear
        const fidl::WireResult result = client->GetInfo();
        if (!result.ok()) {
          FX_PLOGS(ERROR, result.status()) << "Failed to get info";
          return result.status();
        }
        const fidl::WireResponse response = result.value();
        if (zx_status_t status = response.status; status != ZX_OK) {
          FX_PLOGS(ERROR, status) << "Failed to get info";
          return status;
        }
        info = *response.info;
        if (!info.state) {
          config->SetMaxPL1();
        }
      }

      if (temp > info.active_trip[0] && !config->IsAtMin()) {
        // Decrease power limit
        config->SetMinPL1();
      }
    }
  }
  // Do not return so that the compiler will catch it if this becomes reachable.
}

int main(int argc, char** argv) {
  zx_status_t status = RunThermd();

  // RunThermd never returns successfully, so always treat this as an error path.
  FX_LOGS(ERROR) << "Exited with status: " << zx_status_get_string(status);

  // TODO(https://fxbug.dev/42179909): Hang around. If we exit before archivist has started, our logs
  // will be lost, and it's important that we know that thermd is failing and why.
  std::promise<void>().get_future().wait();

  return -1;
}
