/*
 * Copyright (C) 2016 Intel Corporation. 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 "test_va_api_fixture.h"

#include <algorithm>
#include <functional>

#include <fcntl.h> // for O_RDWR
#include <limits>
#include <unistd.h> // for close()
#include <va/va_drm.h>

namespace VAAPI {

VAAPIFixture::VAAPIFixture()
    : ::testing::Test::Test()
    , m_vaDisplay(NULL)
    , m_restoreDriverName(getenv("LIBVA_DRIVER_NAME"))
    , m_drmHandle(-1)
    , drmDevicePaths({ "/dev/dri/renderD128", "/dev/dri/card0" })
    , m_configID(VA_INVALID_ID)
    , m_contextID(VA_INVALID_ID)
    , m_bufferID(VA_INVALID_ID)
    , m_skip("")
{
    return;
}

VAAPIFixture::~VAAPIFixture()
{
    m_vaDisplay = NULL;
    if (m_drmHandle >= 0)
        close(m_drmHandle);
    m_drmHandle = -1;

    // Ensure LIBVA_DRIVER_NAME environment is restored to its original
    // setting so successive tests use the expected driver.
    unsetenv("LIBVA_DRIVER_NAME");
    if (m_restoreDriverName)
        setenv("LIBVA_DRIVER_NAME", m_restoreDriverName, 1);

    if (not m_skip.empty()) {
        EXPECT_FALSE(HasFailure())
            << "skip message is set, but something failed";
        if (not HasFailure()) {
            RecordProperty("skipped", true);
            std::cout << "[ SKIPPED ] " << m_skip << std::endl;
        }
    }
}

VADisplay VAAPIFixture::getDisplay()
{
    uint32_t i;

    for (i = 0; i < sizeof(drmDevicePaths) / sizeof(*drmDevicePaths); i++) {
        m_drmHandle = open(drmDevicePaths[i].c_str(), O_RDWR);
        if (m_drmHandle < 0)
            continue;
        m_vaDisplay = vaGetDisplayDRM(m_drmHandle);

        if (m_vaDisplay)
            return m_vaDisplay;
    }

    return NULL;
}

VADisplay VAAPIFixture::doInitialize()
{
    VADisplay vaDisplay;
    VAStatus status;
    int majorVersion, minorVersion;

    vaDisplay = getDisplay();
    EXPECT_TRUE(vaDisplay);
    if (!vaDisplay) {
        return NULL;
    }

    status = vaInitialize(vaDisplay, &majorVersion, &minorVersion);
    EXPECT_STATUS(status);
    if (status != VA_STATUS_SUCCESS) {
        return NULL;
    }

    return vaDisplay;
}

void VAAPIFixture::queryConfigProfiles(Profiles& profiles) const
{
    const int maxProfiles = vaMaxNumProfiles(m_vaDisplay);
    ASSERT_GT(maxProfiles, 0);
    profiles.resize(maxProfiles);

    int numProfiles(0);
    EXPECT_STATUS(
        vaQueryConfigProfiles(m_vaDisplay, profiles.data(), &numProfiles));

    if (not HasFailure()) {
        ASSERT_LE(numProfiles, maxProfiles);
        ASSERT_GT(numProfiles, 0);
        profiles.resize(numProfiles);
    } else {
        profiles.clear();
    }
}

void VAAPIFixture::queryConfigEntrypoints(const VAProfile& profile,
    Entrypoints& entrypoints, const VAStatus& expectation) const
{
    const int maxEntrypoints = vaMaxNumEntrypoints(m_vaDisplay);
    ASSERT_GT(maxEntrypoints, 0);
    entrypoints.resize(maxEntrypoints);

    int numEntrypoints(0);
    EXPECT_STATUS_EQ(
        expectation,
        vaQueryConfigEntrypoints(m_vaDisplay, profile, entrypoints.data(),
            &numEntrypoints));

    if ((VA_STATUS_SUCCESS == expectation) and not HasFailure()) {
        ASSERT_LE(numEntrypoints, maxEntrypoints);
        ASSERT_GT(numEntrypoints, 0);
        entrypoints.resize(numEntrypoints);
    } else {
        entrypoints.clear();
    }
}

VAStatus VAAPIFixture::getSupportStatus(const VAProfile& profile,
    const VAEntrypoint& entrypoint) const
{
    Profiles profiles;
    queryConfigProfiles(profiles);

    const auto pBegin(profiles.begin());
    const auto pEnd(profiles.end());
    if (std::find(pBegin, pEnd, profile) != pEnd) {
        Entrypoints entrypoints;
        queryConfigEntrypoints(profile, entrypoints);

        const auto eBegin(entrypoints.begin());
        const auto eEnd(entrypoints.end());
        return (std::find(eBegin, eEnd, entrypoint) != eEnd) ?
            VA_STATUS_SUCCESS : VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
    }

    return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
}

bool VAAPIFixture::isSupported(const VAProfile& profile,
    const VAEntrypoint& entrypoint) const
{
    return VA_STATUS_SUCCESS == getSupportStatus(profile, entrypoint);
}

void VAAPIFixture::getConfigAttributes(const VAProfile& profile,
    const VAEntrypoint& entrypoint, ConfigAttributes& attribs,
    const VAStatus& expectation) const
{
    const bool defaults(attribs.empty());

    if (defaults) {
        // fill config attributes with default config attributes
        const auto op = [](const VAConfigAttribType& t) {
            return VAConfigAttrib{type: t, value: VA_ATTRIB_NOT_SUPPORTED};
        };
        std::transform(g_vaConfigAttribTypes.begin(),
            g_vaConfigAttribTypes.end(), std::back_inserter(attribs), op);
    }

    ASSERT_FALSE(attribs.empty());

    EXPECT_STATUS_EQ(
        expectation,
        vaGetConfigAttributes(
            m_vaDisplay, profile, entrypoint, attribs.data(), attribs.size()));

    if (defaults) {
        // remove unsupported config attributes
        const auto begin(attribs.begin());
        const auto end(attribs.end());
        const auto predicate = [](const VAConfigAttrib& a) {
            return a.value == VA_ATTRIB_NOT_SUPPORTED;
        };
        attribs.erase(std::remove_if(begin, end, predicate), end);
    }
}

void VAAPIFixture::createConfig(const VAProfile& profile,
    const VAEntrypoint& entrypoint, const ConfigAttributes& attribs,
    const VAStatus& expectation)
{
    ASSERT_INVALID_ID(m_configID)
        << "test logic error: did you forget to call destroyConfig?";

    EXPECT_STATUS_EQ(
        expectation,
        vaCreateConfig(m_vaDisplay, profile, entrypoint,
            (attribs.size() != 0 ?
                const_cast<VAConfigAttrib*>(attribs.data()) : NULL),
            attribs.size(), &m_configID))
        << "profile    = " << profile << std::endl
        << "entrypoint = " << entrypoint << std::endl
        << "numAttribs = " << attribs.size();

    if (expectation == VA_STATUS_SUCCESS) {
        EXPECT_ID(m_configID);
    } else {
        EXPECT_INVALID_ID(m_configID);
    }
}

void VAAPIFixture::queryConfigAttributes(
    const VAProfile& expectedProfile, const VAEntrypoint& expectedEntrypoint,
    ConfigAttributes& attributes, const VAStatus& expectedStatus) const
{
    VAProfile actualProfile;
    VAEntrypoint actualEntrypoint;
    int numAttributes(0);

    ASSERT_TRUE(attributes.empty())
        << "test logic error: attributes must be empty";

    const int maxAttributes = vaMaxNumConfigAttributes(m_vaDisplay);

    ASSERT_GT(maxAttributes, 0);

    attributes.resize(maxAttributes);

    EXPECT_STATUS_EQ(
        expectedStatus,
        vaQueryConfigAttributes(m_vaDisplay, m_configID, &actualProfile,
            &actualEntrypoint, attributes.data(), &numAttributes));

    if (expectedStatus == VA_STATUS_SUCCESS) {
        EXPECT_EQ(expectedProfile, actualProfile);
        EXPECT_EQ(expectedEntrypoint, actualEntrypoint);
        ASSERT_LE(numAttributes, maxAttributes);
        ASSERT_GT(numAttributes, 0);

        attributes.resize(numAttributes);

        // reported config attributes should be supported
        for (const auto& attribute : attributes) {
            EXPECT_NE(VA_ATTRIB_NOT_SUPPORTED, attribute.value);
        }
    } else {
        attributes.clear();
    }
}

void VAAPIFixture::destroyConfig(const VAStatus& expectation)
{
    EXPECT_STATUS_EQ(expectation, vaDestroyConfig(m_vaDisplay, m_configID));
    m_configID = VA_INVALID_ID;
}

void VAAPIFixture::querySurfaceAttributes(SurfaceAttributes& attribs) const
{
    ASSERT_TRUE(attribs.empty())
        << "test logic error: surface attributes must be empty";

    unsigned numAttribs(0);

    ASSERT_STATUS(vaQuerySurfaceAttributes(m_vaDisplay, m_configID, NULL,
        &numAttribs));

    ASSERT_GT(numAttribs, 0u);

    attribs.resize(numAttribs);

    ASSERT_STATUS(vaQuerySurfaceAttributes(m_vaDisplay, m_configID,
        attribs.data(), &numAttribs));

    ASSERT_GT(numAttribs, 0u);
    EXPECT_GE(attribs.size(), numAttribs);

    attribs.resize(numAttribs);

    const uint32_t flags = 0x0 | VA_SURFACE_ATTRIB_GETTABLE
        | VA_SURFACE_ATTRIB_SETTABLE;

    for (const auto& attrib : attribs) {
        EXPECT_NE(attrib.flags & flags,
            (uint32_t)VA_SURFACE_ATTRIB_NOT_SUPPORTED);
        EXPECT_GE(attrib.value.type, VAGenericValueTypeInteger);
        EXPECT_LE(attrib.value.type, VAGenericValueTypeFunc);
    }
}

void VAAPIFixture::getMinMaxSurfaceResolution(
    Resolution& minRes, Resolution& maxRes) const
{
    const Resolution::DataType maxVal =
        std::numeric_limits<Resolution::DataType>::max();

    // set default resolutions
    minRes.width = 1;
    minRes.height = 1;
    maxRes.width = maxVal;
    maxRes.height = maxVal;

    SurfaceAttributes attribs;
    querySurfaceAttributes(attribs);

    SurfaceAttributes::const_iterator match;
    const SurfaceAttributes::const_iterator begin(attribs.begin());
    const SurfaceAttributes::const_iterator end(attribs.end());

    // minimum surface width
    match = std::find_if(begin, end, [](const VASurfaceAttrib& a)
        {return a.type == VASurfaceAttribMinWidth;});
    if (match != end) {
        EXPECT_EQ(VAGenericValueTypeInteger, match->value.type);
        ASSERT_GE(match->value.value.i, 1);
        ASSERT_LE((Resolution::DataType)match->value.value.i, maxVal);
        minRes.width = match->value.value.i;
    }

    // minimum surface height
    match = std::find_if(begin, end, [](const VASurfaceAttrib& a)
        {return a.type == VASurfaceAttribMinHeight;});
    if (match != end) {
        EXPECT_EQ(VAGenericValueTypeInteger, match->value.type);
        ASSERT_GE(match->value.value.i, 1);
        ASSERT_LE((Resolution::DataType)match->value.value.i, maxVal);
        minRes.height = match->value.value.i;
    }

    // maximum surface width
    match = std::find_if(begin, end, [](const VASurfaceAttrib& a)
        {return a.type == VASurfaceAttribMaxWidth;});
    if (match != end) {
        EXPECT_EQ(VAGenericValueTypeInteger, match->value.type);
        ASSERT_GE(match->value.value.i, 1);
        ASSERT_LE((Resolution::DataType)match->value.value.i, maxVal);
        maxRes.width = match->value.value.i;
    }

    // maximum surface height
    match = std::find_if(begin, end, [](const VASurfaceAttrib& a)
        {return a.type == VASurfaceAttribMaxHeight;});
    if (match != end) {
        EXPECT_EQ(VAGenericValueTypeInteger, match->value.type);
        ASSERT_GE(match->value.value.i, 1);
        ASSERT_LE((Resolution::DataType)match->value.value.i, maxVal);
        maxRes.height = match->value.value.i;
    }

    EXPECT_LE(minRes, maxRes);
}

void VAAPIFixture::createSurfaces(Surfaces& surfaces, const unsigned format,
    const Resolution& resolution, const SurfaceAttributes& attribs,
    const VAStatus& expectation) const
{
    ASSERT_GT(surfaces.size(), 0u)
        << "test logic error: surfaces must not be emtpy";
    for (const auto& surface : surfaces) {
        ASSERT_INVALID_ID(surface)
            << "test logic error: surfaces must all be VA_INVALID_SURFACE";
    }

    ASSERT_STATUS_EQ(
        expectation,
        vaCreateSurfaces(m_vaDisplay, format, resolution.width,
            resolution.height, surfaces.data(), surfaces.size(),
            (attribs.size() != 0 ?
                const_cast<VASurfaceAttrib*>(attribs.data()) : NULL),
            attribs.size()));

    if (expectation == VA_STATUS_SUCCESS) {
        for (const auto& surface : surfaces) {
            ASSERT_ID(surface);
        }
    }
}

void VAAPIFixture::destroySurfaces(Surfaces& surfaces) const
{
    if (surfaces.size() != 0) {
        EXPECT_STATUS(vaDestroySurfaces(m_vaDisplay, surfaces.data(),
            surfaces.size()));
    }
}

void VAAPIFixture::createBuffer(const VABufferType& bufferType,
    const size_t bufferSize, const VAStatus& expectation)
{
    ASSERT_INVALID_ID(m_bufferID)
        << "test logic error: did you forget to call destroyBuffer?";

    EXPECT_STATUS_EQ(
        expectation,
        vaCreateBuffer(m_vaDisplay, m_contextID, bufferType, bufferSize,
            1, NULL, &m_bufferID));
}

void VAAPIFixture::destroyBuffer(const VAStatus& expectation)
{
    EXPECT_STATUS_EQ(expectation, vaDestroyBuffer(m_vaDisplay, m_bufferID));
    m_bufferID = VA_INVALID_ID;
}

void VAAPIFixture::doCreateContext(const Resolution& resolution,
    const VAStatus& expectation)
{
    m_contextID = 0;
    ASSERT_STATUS_EQ(expectation,
                     vaCreateContext(m_vaDisplay, m_configID, resolution.width,
                                     resolution.height, VA_PROGRESSIVE,
                                     NULL, 0, &m_contextID));
}

void VAAPIFixture::doDestroyContext(const VAStatus& expectation)
{
    ASSERT_STATUS_EQ(expectation, vaDestroyContext(m_vaDisplay, m_contextID));
}

void VAAPIFixture::doTerminate()
{
    EXPECT_STATUS(vaTerminate(m_vaDisplay));
}

void VAAPIFixture::skipTest(const std::string& message)
{
    ASSERT_FALSE(message.empty())
        << "test logic error: skip message cannot be empty";
    ASSERT_TRUE(m_skip.empty())
        << "test logic error: test already marked as skipped";

    m_skip = message;
}

void VAAPIFixture::skipTest(const VAProfile& profile,
    const VAEntrypoint& entrypoint)
{
    std::ostringstream oss;
    oss << profile << " / " << entrypoint << " not supported on this hardware";
    skipTest(oss.str());
}

TEST_F(VAAPIFixture, getDisplay)
{
    VADisplay vaDisplay;

    vaDisplay = getDisplay();
    ASSERT_TRUE(vaDisplay);
    EXPECT_STATUS(vaTerminate(vaDisplay));
}

} // namespace VAAPI
