/*
 * 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_query2(device_, MAGMA_QUERY_VENDOR_ID, &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));
}
