/*
 * Copyright 2017, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef MEDIA_HIDL_TEST_COMMON_H
#define MEDIA_HIDL_TEST_COMMON_H

#ifdef __LP64__
#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
#endif

#include <getopt.h>

#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
#include <android/hardware/graphics/common/1.0/types.h>
#include <android/hardware/graphics/common/1.1/types.h>
#include <android/hardware/graphics/common/1.2/types.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <android/hardware/graphics/mapper/2.0/types.h>
#include <android/hardware/graphics/mapper/3.0/IMapper.h>
#include <android/hardware/graphics/mapper/3.0/types.h>
#include <media/stagefright/foundation/ALooper.h>
#include <utils/Condition.h>
#include <utils/List.h>
#include <utils/Mutex.h>

#include <media/openmax/OMX_Index.h>
#include <media/openmax/OMX_Core.h>
#include <media/openmax/OMX_Component.h>
#include <media/openmax/OMX_IndexExt.h>
#include <media/openmax/OMX_AudioExt.h>
#include <media/openmax/OMX_VideoExt.h>

#include <VtsHalHidlTargetTestEnvBase.h>

/* TIME OUTS (Wait time in dequeueMessage()) */

/* As component is switching states (loaded<->idle<->execute), dequeueMessage()
 * expects the events to be received within this duration */
#define DEFAULT_TIMEOUT 100000
// b/70933963
#define RELAXED_TIMEOUT 400000
/* Time interval between successive Input/Output enqueues */
#define DEFAULT_TIMEOUT_Q 2000
/* While the component is amidst a process call, asynchronous commands like
 * flush, change states can get delayed (at max by process call time). Instead
 * of waiting on DEFAULT_TIMEOUT, we give an additional leeway. */
#define DEFAULT_TIMEOUT_PE 500000

/* Breakout Timeout :: 5 sec*/
#define TIMEOUT_COUNTER_Q (5000000 / DEFAULT_TIMEOUT_Q)
#define TIMEOUT_COUNTER_PE (5000000 / DEFAULT_TIMEOUT_PE)

/*
 * Random Index used for monkey testing while get/set parameters
 */
#define RANDOM_INDEX 1729

#define ALIGN_POWER_OF_TWO(value, n) \
    (((value) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1))

enum bufferOwner {
    client,
    component,
    unknown,
};

/*
 * TODO: below definitions are borrowed from Conversion.h.
 * This is not the ideal way to do it. Loose these definitions once you
 * include Conversion.h
 */
inline uint32_t toRawIndexType(OMX_INDEXTYPE l) {
    return static_cast<uint32_t>(l);
}

inline android::hardware::media::omx::V1_0::Status toStatus(
    android::status_t l) {
    return static_cast<android::hardware::media::omx::V1_0::Status>(l);
}

inline hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
    hidl_vec<uint8_t> t;
    t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
    return t;
}

inline uint32_t toRawCommandType(OMX_COMMANDTYPE l) {
    return static_cast<uint32_t>(l);
}

/*
 * struct definitions
 */
struct BufferInfo {
    uint32_t id;
    bufferOwner owner;
    android::hardware::media::omx::V1_0::CodecBuffer omxBuffer;
    ::android::sp<IMemory> mMemory;
    int32_t slot;
};

struct FrameData {
    int bytesCount;
    uint32_t flags;
    uint32_t timestamp;
};

/*
 * Handle Callback functions EmptythisBuffer(), FillthisBuffer(),
 * EventHandler()
 */
struct CodecObserver : public IOmxObserver {
   public:
    CodecObserver(std::function<void(Message, const BufferInfo*)> fn)
        : callBack(fn) {}
    Return<void> onMessages(const hidl_vec<Message>& messages) override {
        android::Mutex::Autolock autoLock(msgLock);
        for (hidl_vec<Message>::const_iterator it = messages.begin();
             it != messages.end(); ++it) {
            msgQueue.push_back(*it);
        }
        msgCondition.signal();
        return Void();
    }
    android::hardware::media::omx::V1_0::Status dequeueMessage(
        Message* msg, int64_t timeoutUs,
        android::Vector<BufferInfo>* iBuffers = nullptr,
        android::Vector<BufferInfo>* oBuffers = nullptr) {
        int64_t finishBy = android::ALooper::GetNowUs() + timeoutUs;
        for (;;) {
            android::Mutex::Autolock autoLock(msgLock);
            android::List<Message>::iterator it = msgQueue.begin();
            while (it != msgQueue.end()) {
                if (it->type ==
                    android::hardware::media::omx::V1_0::Message::Type::EVENT) {
                    *msg = *it;
                    if (callBack) callBack(*it, nullptr);
                    it = msgQueue.erase(it);
                    // OMX_EventBufferFlag event is sent when the component has
                    // processed a buffer with its EOS flag set. This event is
                    // not sent by soft omx components. Vendor components can
                    // send this. From IOMX point of view, we will ignore this
                    // event.
                    if (msg->data.eventData.event == OMX_EventBufferFlag)
                        continue;
                    return ::android::hardware::media::omx::V1_0::Status::OK;
                } else if (it->type == android::hardware::media::omx::V1_0::
                                           Message::Type::FILL_BUFFER_DONE) {
                    if (oBuffers) {
                        size_t i;
                        for (i = 0; i < oBuffers->size(); ++i) {
                            if ((*oBuffers)[i].id ==
                                it->data.bufferData.buffer) {
                                if (callBack) callBack(*it, &(*oBuffers)[i]);
                                oBuffers->editItemAt(i).owner = client;
                                it = msgQueue.erase(it);
                                break;
                            }
                        }
                        EXPECT_LE(i, oBuffers->size());
                    }
                } else if (it->type == android::hardware::media::omx::V1_0::
                                           Message::Type::EMPTY_BUFFER_DONE) {
                    if (iBuffers) {
                        size_t i;
                        for (i = 0; i < iBuffers->size(); ++i) {
                            if ((*iBuffers)[i].id ==
                                it->data.bufferData.buffer) {
                                if (callBack) callBack(*it, &(*iBuffers)[i]);
                                iBuffers->editItemAt(i).owner = client;
                                it = msgQueue.erase(it);
                                break;
                            }
                        }
                        EXPECT_LE(i, iBuffers->size());
                    }
                } else {
                    EXPECT_TRUE(false) << "Received unexpected message";
                    ++it;
                }
            }
            int64_t delayUs = finishBy - android::ALooper::GetNowUs();
            if (delayUs < 0) return toStatus(android::TIMED_OUT);
            (timeoutUs < 0)
                ? msgCondition.wait(msgLock)
                : msgCondition.waitRelative(msgLock, delayUs * 1000ll);
        }
    }

    android::List<Message> msgQueue;
    android::Mutex msgLock;
    android::Condition msgCondition;
    std::function<void(Message, const BufferInfo*)> callBack;
};

/*
 * Useful Wrapper utilities
 */
template <class T>
void InitOMXParams(T* params) {
    params->nSize = sizeof(T);
    params->nVersion.s.nVersionMajor = 1;
    params->nVersion.s.nVersionMinor = 0;
    params->nVersion.s.nRevision = 0;
    params->nVersion.s.nStep = 0;
}

template <class T>
Return<android::hardware::media::omx::V1_0::Status> getParam(
    sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, T* params) {
    android::hardware::media::omx::V1_0::Status status;
    InitOMXParams(params);
    omxNode->getParameter(
        toRawIndexType(omxIdx), inHidlBytes(params, sizeof(*params)),
        [&status, &params](android::hardware::media::omx::V1_0::Status _s,
                           hidl_vec<uint8_t> const& outParams) {
            status = _s;
            std::copy(outParams.data(), outParams.data() + outParams.size(),
                      static_cast<uint8_t*>(static_cast<void*>(params)));
        });
    return status;
}

template <class T>
Return<android::hardware::media::omx::V1_0::Status> setParam(
    sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, T* params) {
    InitOMXParams(params);
    return omxNode->setParameter(toRawIndexType(omxIdx),
                                 inHidlBytes(params, sizeof(*params)));
}

template <class T>
Return<android::hardware::media::omx::V1_0::Status> getPortParam(
    sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, OMX_U32 nPortIndex, T* params) {
    android::hardware::media::omx::V1_0::Status status;
    InitOMXParams(params);
    params->nPortIndex = nPortIndex;
    omxNode->getParameter(
        toRawIndexType(omxIdx), inHidlBytes(params, sizeof(*params)),
        [&status, &params](android::hardware::media::omx::V1_0::Status _s,
                           hidl_vec<uint8_t> const& outParams) {
            status = _s;
            std::copy(outParams.data(), outParams.data() + outParams.size(),
                      static_cast<uint8_t*>(static_cast<void*>(params)));
        });
    return status;
}

template <class T>
Return<android::hardware::media::omx::V1_0::Status> setPortParam(
    sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, OMX_U32 nPortIndex, T* params) {
    InitOMXParams(params);
    params->nPortIndex = nPortIndex;
    return omxNode->setParameter(toRawIndexType(omxIdx),
                                 inHidlBytes(params, sizeof(*params)));
}

template <class T>
Return<android::hardware::media::omx::V1_0::Status> getPortConfig(
    sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, OMX_U32 nPortIndex, T* params) {
    android::hardware::media::omx::V1_0::Status status;
    InitOMXParams(params);
    params->nPortIndex = nPortIndex;
    omxNode->getConfig(
        toRawIndexType(omxIdx), inHidlBytes(params, sizeof(*params)),
        [&status, &params](android::hardware::media::omx::V1_0::Status _s,
                           hidl_vec<uint8_t> const& outParams) {
            status = _s;
            std::copy(outParams.data(), outParams.data() + outParams.size(),
                      static_cast<uint8_t*>(static_cast<void*>(params)));
        });
    return status;
}

template <class T>
Return<android::hardware::media::omx::V1_0::Status> setPortConfig(
    sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, OMX_U32 nPortIndex, T* params) {
    InitOMXParams(params);
    params->nPortIndex = nPortIndex;
    return omxNode->setConfig(toRawIndexType(omxIdx),
                              inHidlBytes(params, sizeof(*params)));
}

/*
 * common functions declarations
 */
struct GrallocV2 {
    using Format = android::hardware::graphics::common::V1_0::PixelFormat;
    using Usage = android::hardware::hidl_bitfield<
            android::hardware::graphics::common::V1_0::BufferUsage>;

    using IAllocator = android::hardware::graphics::allocator::V2_0::IAllocator;

    using IMapper = android::hardware::graphics::mapper::V2_0::IMapper;
    using Error = android::hardware::graphics::mapper::V2_0::Error;
    using Descriptor = android::hardware::graphics::mapper::V2_0::BufferDescriptor;
    using YCbCrLayout = android::hardware::graphics::mapper::V2_0::YCbCrLayout;
    using DescriptorInfo = IMapper::BufferDescriptorInfo;
    using Rect = IMapper::Rect;
};

struct GrallocV3 {
    using Format = android::hardware::graphics::common::V1_2::PixelFormat;
    using Usage = android::hardware::hidl_bitfield<
            android::hardware::graphics::common::V1_2::BufferUsage>;

    using IAllocator = android::hardware::graphics::allocator::V3_0::IAllocator;

    using IMapper = android::hardware::graphics::mapper::V3_0::IMapper;
    using Error = android::hardware::graphics::mapper::V3_0::Error;
    using Descriptor = android::hardware::graphics::mapper::V3_0::BufferDescriptor;
    using YCbCrLayout = android::hardware::graphics::mapper::V3_0::YCbCrLayout;
    using DescriptorInfo = IMapper::BufferDescriptorInfo;
    using Rect = IMapper::Rect;
};

Return<android::hardware::media::omx::V1_0::Status> setRole(
    sp<IOmxNode> omxNode, const char* role);

Return<android::hardware::media::omx::V1_0::Status> setPortBufferSize(
    sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_U32 size);

Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
    sp<IOmxNode> omxNode, OMX_U32 portIndex,
    OMX_VIDEO_CODINGTYPE eCompressionFormat, OMX_COLOR_FORMATTYPE eColorFormat,
    OMX_U32 xFramerate);

Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
    sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE eEncoding);

void allocateBuffer(sp<IOmxNode> omxNode, BufferInfo* buffer, OMX_U32 portIndex,
                    OMX_U32 nBufferSize, PortMode portMode);

void allocatePortBuffers(sp<IOmxNode> omxNode,
                         android::Vector<BufferInfo>* buffArray,
                         OMX_U32 portIndex,
                         PortMode portMode = PortMode::PRESET_BYTE_BUFFER,
                         bool allocGrap = false);

void changeStateLoadedtoIdle(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
                             android::Vector<BufferInfo>* iBuffer,
                             android::Vector<BufferInfo>* oBuffer,
                             OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
                             PortMode* portMode = nullptr,
                             bool allocGrap = false);

void changeStateIdletoLoaded(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
                             android::Vector<BufferInfo>* iBuffer,
                             android::Vector<BufferInfo>* oBuffer,
                             OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput);

void changeStateIdletoExecute(sp<IOmxNode> omxNode, sp<CodecObserver> observer);

void changeStateExecutetoIdle(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
                              android::Vector<BufferInfo>* iBuffer,
                              android::Vector<BufferInfo>* oBuffer);

size_t getEmptyBufferID(android::Vector<BufferInfo>* buffArray);

void dispatchOutputBuffer(sp<IOmxNode> omxNode,
                          android::Vector<BufferInfo>* buffArray,
                          size_t bufferIndex,
                          PortMode portMode = PortMode::PRESET_BYTE_BUFFER);

void dispatchInputBuffer(sp<IOmxNode> omxNode,
                         android::Vector<BufferInfo>* buffArray,
                         size_t bufferIndex, int bytesCount, uint32_t flags,
                         uint64_t timestamp,
                         PortMode portMode = PortMode::PRESET_BYTE_BUFFER);

void flushPorts(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
                android::Vector<BufferInfo>* iBuffer,
                android::Vector<BufferInfo>* oBuffer, OMX_U32 kPortIndexInput,
                OMX_U32 kPortIndexOutput,
                int64_t timeoutUs = DEFAULT_TIMEOUT_PE);

typedef void (*portreconfig)(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
                             android::Vector<BufferInfo>* iBuffer,
                             android::Vector<BufferInfo>* oBuffer,
                             OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
                             Message msg, PortMode oPortMode, void* args);
void testEOS(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
             android::Vector<BufferInfo>* iBuffer,
             android::Vector<BufferInfo>* oBuffer, bool signalEOS,
             bool& eosFlag, PortMode* portMode = nullptr,
             portreconfig fptr = nullptr, OMX_U32 kPortIndexInput = 0,
             OMX_U32 kPortIndexOutput = 1, void* args = nullptr);

// A class for test environment setup
class ComponentTestEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
   private:
    typedef ::testing::VtsHalHidlTargetTestEnvBase Super;

   public:
    virtual void registerTestServices() override { registerTestService<IOmx>(); }

    ComponentTestEnvironment() : res("/sdcard/media/") {}

    void setComponent(const char* _component) { component = _component; }

    void setRole(const char* _role) { role = _role; }

    void setRes(const char* _res) { res = _res; }

    const hidl_string getInstance() { return Super::getServiceName<IOmx>(); }

    const hidl_string getComponent() const { return component; }

    const hidl_string getRole() const { return role; }

    const hidl_string getRes() const { return res; }

    int initFromOptions(int argc, char** argv) {
        static struct option options[] = {{"component", required_argument, 0, 'C'},
                                          {"role", required_argument, 0, 'R'},
                                          {"res", required_argument, 0, 'P'},
                                          {0, 0, 0, 0}};

        while (true) {
            int index = 0;
            int c = getopt_long(argc, argv, "C:R:P:", options, &index);
            if (c == -1) {
                break;
            }

            switch (c) {
                case 'C':
                    setComponent(optarg);
                    break;
                case 'R':
                    setRole(optarg);
                    break;
                case 'P':
                    setRes(optarg);
                    break;
                case '?':
                    break;
            }
        }

        if (optind < argc) {
            fprintf(stderr,
                    "unrecognized option: %s\n\n"
                    "usage: %s <gtest options> <test options>\n\n"
                    "test options are:\n\n"
                    "-C, --component: OMX component to test\n"
                    "-R, --role: OMX component Role\n"
                    "-P, --res: Resource files directory location\n",
                    argv[optind ?: 1], argv[0]);
            return 2;
        }
        return 0;
    }

   private:
    hidl_string instance;
    hidl_string component;
    hidl_string role;
    hidl_string res;
};

#endif  // MEDIA_HIDL_TEST_COMMON_H
