/*
 * 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)
    , 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()
{
    typedef std::vector<std::string> DevicePaths;
    typedef DevicePaths::const_iterator DevicePathsIterator;

    static DevicePaths paths({"/dev/dri/renderD128", "/dev/dri/card0"});

    const DevicePathsIterator endIt(paths.end());
    for (DevicePathsIterator it(paths.begin()); it != endIt; ++it) {
        m_drmHandle = open(it->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) << "failed to initialize vaapi";
    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
