// Copyright 2022 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 <fidl/fuchsia.hardware.interrupt/cpp/fidl.h>
#include <lib/component/outgoing/cpp/handlers.h>
#include <lib/component/outgoing/cpp/outgoing_directory.h>

#include <gtest/gtest.h>

#include "src/devices/lib/fragment-irq/dfv1/fragment-irq.h"
#include "src/devices/testing/mock-ddk/mock-device.h"
#include "src/lib/testing/loop_fixture/test_loop_fixture.h"

namespace fint = fuchsia_hardware_interrupt;

class Dfv1Test : public gtest::TestLoopFixture, public fidl::Server<fint::Provider> {
 public:
  void SetUp() override {
    root_ = MockDevice::FakeRootParent();
    auto provider_handler = [this](fidl::ServerEnd<fint::Provider> request) {
      fidl::BindServer(dispatcher(), std::move(request), this);
    };
    fint::Service::InstanceHandler handler({.provider = std::move(provider_handler)});

    auto result = outgoing_.AddService<fuchsia_hardware_interrupt::Service>(std::move(handler));
    ASSERT_TRUE(result.is_ok());

    auto endpoints = fidl::Endpoints<fuchsia_io::Directory>::Create();

    ASSERT_EQ(ZX_OK, outgoing_.Serve(std::move(endpoints.server)).status_value());

    root_->AddFidlService(fint::Service::Name, std::move(endpoints.client), "irq001");
  }

  void Get(GetCompleter::Sync& completer) override {
    fint::ProviderGetResponse ret;
    zx::interrupt fake;
    ASSERT_EQ(ZX_OK, zx::interrupt::create(zx::resource(), 0, ZX_INTERRUPT_VIRTUAL, &fake));
    ret.interrupt() = std::move(fake);

    completer.Reply(fit::ok(std::move(ret)));
  }

 protected:
  std::shared_ptr<zx_device> root_;
  component::OutgoingDirectory outgoing_ = component::OutgoingDirectory(dispatcher());
};

TEST_F(Dfv1Test, TestGetInterrupt) {
  sync_completion_t done;
  std::thread spare([this, &done]() {
    ASSERT_EQ(ZX_OK, fragment_irq::GetInterrupt(root_.get(), 1).status_value());
    sync_completion_signal(&done);
  });

  do {
    RunLoopUntilIdle();
  } while (sync_completion_wait(&done, ZX_TIME_INFINITE_PAST) != ZX_OK);

  spare.join();
}

TEST_F(Dfv1Test, TestGetInterruptBadFragment) {
  sync_completion_t done;
  std::thread spare([this, &done]() {
    ASSERT_NE(ZX_OK, fragment_irq::GetInterrupt(root_.get(), 0u).status_value());
    sync_completion_signal(&done);
  });

  do {
    RunLoopUntilIdle();
  } while (sync_completion_wait(&done, ZX_TIME_INFINITE_PAST) != ZX_OK);

  spare.join();
}
