// 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 <fuchsia/hardware/pciroot/c/banjo.h>
#include <inttypes.h>
#include <lib/ddk/debug.h>
#include <limits.h>
#include <sys/types.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/iommu.h>
#include <zircon/syscalls/resource.h>
#include <zircon/threads.h>

#include <variant>
#include <vector>

#include <acpica/acpi.h>
#include <fbl/auto_lock.h>

#include "acpi-dev/dev-ec.h"
#include "acpi-private.h"
#include "acpi.h"
#include "dev.h"
#include "errors.h"
#include "methods.h"
#include "power.h"
#include "src/devices/board/lib/acpi/device.h"
#include "src/devices/board/lib/acpi/manager.h"
#include "src/devices/board/lib/acpi/resources.h"
#include "src/devices/board/lib/acpi/status.h"
#include "src/devices/lib/iommu/iommu.h"
#include "sysmem.h"

namespace {

const std::string_view hid_from_acpi_devinfo(const ACPI_DEVICE_INFO& info) {
  if ((info.Valid & ACPI_VALID_HID) && (info.HardwareId.Length > 0) &&
      ((info.HardwareId.Length - 1) <= sizeof(uint64_t))) {
    // ACPICA string lengths include the NULL terminator.
    return std::string_view{info.HardwareId.String, info.HardwareId.Length - 1};
  }

  return std::string_view{};
}

}  // namespace

namespace acpi {

acpi::status<UniquePtr<ACPI_DEVICE_INFO>> GetObjectInfo(ACPI_HANDLE obj) {
  ACPI_DEVICE_INFO* raw = nullptr;
  ACPI_STATUS acpi_status = AcpiGetObjectInfo(obj, &raw);
  UniquePtr<ACPI_DEVICE_INFO> ret{raw};

  if (ACPI_SUCCESS(acpi_status)) {
    return acpi::ok(std::move(ret));
  }

  return acpi::error(acpi_status);
}

}  // namespace acpi

zx_status_t acpi_suspend(zx_device_t* device, uint8_t requested_state, bool enable_wake,
                         uint8_t suspend_reason, uint8_t* out_state) {
  switch (suspend_reason & DEVICE_MASK_SUSPEND_REASON) {
    case DEVICE_SUSPEND_REASON_MEXEC: {
      AcpiTerminate();
      return ZX_OK;
    }
    case DEVICE_SUSPEND_REASON_REBOOT:
      // Don't do anything, we expect the higher layers to execute the reboot.
      return ZX_OK;
    case DEVICE_SUSPEND_REASON_POWEROFF:
      poweroff(device);
      exit(0);
    case DEVICE_SUSPEND_REASON_SUSPEND_RAM:
      return suspend_to_ram(device);
    default:
      return ZX_ERR_NOT_SUPPORTED;
  };
}

zx_status_t publish_acpi_devices(acpi::Manager* manager, zx_device_t* platform_bus,
                                 zx_device_t* acpi_root) {
  acpi::Acpi* acpi = manager->acpi();

  auto result = manager->DiscoverDevices();
  if (result.is_error()) {
    zxlogf(INFO, "discover devices failed");
  }
  result = manager->ConfigureDiscoveredDevices();
  if (result.is_error()) {
    zxlogf(INFO, "configure failed");
  }
  result = manager->PublishDevices(platform_bus, fdf::Dispatcher::GetCurrent()->async_dispatcher());

  // Now walk the ACPI namespace looking for devices we understand, and publish
  // them.  For now, publish only the first PCI bus we encounter.
  // TODO(https://fxbug.dev/42158465): remove this when all drivers are removed from the x86 board
  // driver.
  acpi::status<> acpi_status =
      acpi->WalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, MAX_NAMESPACE_DEPTH,
                          [acpi_root, acpi](ACPI_HANDLE object, uint32_t level,
                                            acpi::WalkDirection dir) -> acpi::status<> {
                            // We don't have anything useful to do during the ascent
                            // phase.  Just skip it.
                            if (dir == acpi::WalkDirection::Ascending) {
                              return acpi::ok();
                            }

                            // We are descending.  Grab our object info.
                            acpi::UniquePtr<ACPI_DEVICE_INFO> info;
                            if (auto res = acpi::GetObjectInfo(object); res.is_error()) {
                              return res.take_error();
                            } else {
                              info = std::move(res.value());
                            }

                            // Extract pointers to the hardware ID and the compatible ID
                            // if present. If there is no hardware ID, just skip the
                            // device.
                            const std::string_view hid = hid_from_acpi_devinfo(*info);
                            if (hid.empty()) {
                              return acpi::ok();
                            }

                            // Now, if we recognize the HID, go ahead and deal with
                            // publishing the device.
                            if (hid == EC_HID_STRING) {
                              acpi_ec::EcDevice::Create(acpi_root, acpi, object);
                            }
                            return acpi::ok();
                          });

  if (acpi_status.is_error()) {
    return ZX_ERR_BAD_STATE;
  }

  return ZX_OK;
}
