/*
 * Copyright (c) 2021 The Fuchsia Authors. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <lib/fdio/directory.h>
#include <lib/zx/channel.h>
#include <stdio.h>

#include <filesystem>

#include <gtest/gtest.h>
#include <va/va_magma.h>

class VaTest : public testing::Test {
 public:
  VaTest(uint64_t vendor_id) : vendor_id_(vendor_id) {}

  void SetUp() override {
    for (auto& p : std::filesystem::directory_iterator("/dev/class/gpu")) {
      {
        zx::channel local, remote;
        ASSERT_EQ(ZX_OK, zx::channel::create(0 /*flags*/, &local, &remote));
        ASSERT_EQ(ZX_OK, fdio_service_connect(p.path().c_str(), remote.release()));
        ASSERT_EQ(MAGMA_STATUS_OK, magma_device_import(local.release(), &device_));
      }

      {
        uint64_t vendor_id;
        magma_status_t magma_status = magma_query(device_, MAGMA_QUERY_VENDOR_ID, nullptr, &vendor_id);
        if (magma_status == MAGMA_STATUS_OK && vendor_id == vendor_id_) {
          break;
        }
      }

      magma_device_release(device_);
      device_ = {};
    }

    ASSERT_TRUE(device_);
  }

  void TearDown() override {
    if (device_)
      magma_device_release(device_);
  }

  uint64_t vendor_id_;
  magma_device_t device_{};
};

class IntelVaTest : public VaTest {
 public:
  IntelVaTest() : VaTest(0x8086) {}
};

TEST_F(IntelVaTest, Open) {
  VADisplay display = vaGetDisplayMagma(device_);
  ASSERT_TRUE(display);
  int major_ver, minor_ver;
  EXPECT_EQ(VA_STATUS_SUCCESS, vaInitialize(display, &major_ver, &minor_ver));
  EXPECT_EQ(VA_STATUS_SUCCESS, vaTerminate(display));
}
