// 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/rtc/c/fidl.h>
#include <lib/driver-integration-test/fixture.h>
#include <lib/fdio/fdio.h>
#include <lib/zx/channel.h>
#include <librtc.h>

#include <ddk/platform-defs.h>
#include <zxtest/zxtest.h>

namespace {

using driver_integration_test::IsolatedDevmgr;

// Sandboxed drivers always land at sys/platforom/..
// Below "11" is the hex value of PDEV_VID_TEST
//       "08" is the hex value of our PID - PDEV_PID_FALLBACK_RTC_TEST
//       "fallback-rtc" is the name of our driver (the way used in Bind())
constexpr char kLandingPath[] = "sys/platform/11:0c:0/fallback-rtc";
constexpr uint8_t kMetadata = PDEV_PID_FALLBACK_RTC_TEST;
const board_test::DeviceEntry kDeviceEntry = []() {
  board_test::DeviceEntry entry = {};
  strcpy(entry.name, "fallback_rtc");
  entry.vid = PDEV_VID_TEST;
  entry.pid = PDEV_PID_FALLBACK_RTC_TEST;

  entry.metadata = &kMetadata;
  entry.metadata_size = 1;

  return entry;
}();

class FallbackRTCTest : public zxtest::Test {
  void SetUp() override {
    // Create the isolated dev manager
    fbl::unique_fd rtc_fd;
    IsolatedDevmgr::Args args;
    args.driver_search_paths.push_back("/boot/driver");

    args.device_list.push_back(kDeviceEntry);
    ASSERT_OK(IsolatedDevmgr::Create(&args, &devmgr_));

    // Wait for fallback-rtc to be created
    ASSERT_OK(
        devmgr_integration_test::RecursiveWaitForFile(devmgr_.devfs_root(), kLandingPath, &rtc_fd));

    // Get a FIDL channel to the rtc driver
    ASSERT_OK(fdio_get_service_handle(rtc_fd.release(), rtc_fdio_channel_.reset_and_get_address()));
  }

 protected:
  IsolatedDevmgr devmgr_;
  zx::channel rtc_fdio_channel_;
};

// Checks that the default time is a valid one
TEST_F(FallbackRTCTest, GetInitialDatetimeCheckValid) {
  fuchsia_hardware_rtc_Time rtc;

  ASSERT_OK(fuchsia_hardware_rtc_DeviceGet(rtc_fdio_channel_.get(), &rtc));
  ASSERT_FALSE(rtc_is_invalid(&rtc));
}

// Sets a specific date time and then verifies that the same can be red back
TEST_F(FallbackRTCTest, SetSpecificDatetimeReadBackSame) {
  int op_status;

  // set datetime
  fuchsia_hardware_rtc_Time rtcSet;
  rtcSet.year = 2019;
  rtcSet.month = 5;
  rtcSet.day = 24;
  rtcSet.hours = 19;
  rtcSet.minutes = 42;
  rtcSet.seconds = 9;
  ASSERT_OK(fuchsia_hardware_rtc_DeviceSet(rtc_fdio_channel_.get(), &rtcSet, &op_status));
  ASSERT_OK(op_status);

  // get datetime
  fuchsia_hardware_rtc_Time rtcGet;
  ASSERT_OK(fuchsia_hardware_rtc_DeviceGet(rtc_fdio_channel_.get(), &rtcGet));
  ASSERT_EQ(rtcGet.year, 2019);
  ASSERT_EQ(rtcGet.month, 5);
  ASSERT_EQ(rtcGet.day, 24);
  ASSERT_EQ(rtcGet.hours, 19);
  ASSERT_EQ(rtcGet.minutes, 42);
  ASSERT_EQ(rtcGet.seconds, 9);
}

TEST_F(FallbackRTCTest, SetInvalidDatetimeErrorAndHasNoEffect) {
  fuchsia_hardware_rtc_Time rtc;
  int op_status;

  // set datetime
  rtc.year = 2022;
  rtc.month = 6;
  rtc.day = 27;
  rtc.hours = 11;
  rtc.minutes = 2;
  rtc.seconds = 10;
  ASSERT_OK(fuchsia_hardware_rtc_DeviceSet(rtc_fdio_channel_.get(), &rtc, &op_status));
  ASSERT_OK(op_status);

  // pass invalid date
  rtc.year = 2019;
  rtc.month = 3;
  rtc.day = 32;
  rtc.hours = 17;
  rtc.minutes = 33;
  rtc.seconds = 4;
  ASSERT_OK(fuchsia_hardware_rtc_DeviceSet(rtc_fdio_channel_.get(), &rtc, &op_status));
  ASSERT_STATUS(ZX_ERR_OUT_OF_RANGE, op_status);

  // get datetime and compare with the one that was successfully set above
  ASSERT_OK(fuchsia_hardware_rtc_DeviceGet(rtc_fdio_channel_.get(), &rtc));
  ASSERT_EQ(rtc.year, 2022);
  ASSERT_EQ(rtc.month, 6);
  ASSERT_EQ(rtc.day, 27);
  ASSERT_EQ(rtc.hours, 11);
  ASSERT_EQ(rtc.minutes, 2);
  ASSERT_EQ(rtc.seconds, 10);
}

}  // namespace
