// Copyright (C) 2020 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.

#include "LocalPrebuiltGraph.h"

#include <android-base/logging.h>
#include <dlfcn.h>

#include <functional>
#include <iostream>
#include <mutex>
#include <shared_mutex>
#include <string>
#include <vector>

#include "ClientConfig.pb.h"
#include "InputFrame.h"
#include "PrebuiltGraph.h"
#include "RunnerComponent.h"
#include "prebuilt_interface.h"
#include "types/Status.h"

namespace android {
namespace automotive {
namespace computepipe {
namespace graph {

#define LOAD_FUNCTION(name)                                                        \
    {                                                                              \
        std::string func_name = std::string("PrebuiltComputepipeRunner_") + #name; \
        mPrebuiltGraphInstance->mFn##name =                                        \
                dlsym(mPrebuiltGraphInstance->mHandle, func_name.c_str());         \
        if (mPrebuiltGraphInstance->mFn##name == nullptr) {                        \
            initialized = false;                                                   \
            LOG(ERROR) << std::string(dlerror()) << std::endl;                     \
        }                                                                          \
    }

std::mutex LocalPrebuiltGraph::mCreationMutex;
LocalPrebuiltGraph* LocalPrebuiltGraph::mPrebuiltGraphInstance = nullptr;

// Function to confirm that there would be no further changes to the graph configuration. This
// needs to be called before starting the graph.
Status LocalPrebuiltGraph::handleConfigPhase(const runner::ClientConfig& e) {
    if (mGraphState.load() == PrebuiltGraphState::UNINITIALIZED) {
        return Status::ILLEGAL_STATE;
    }

    // handleConfigPhase is a blocking call, so abort call is pointless for this RunnerEvent.
    if (e.isAborted()) {
        return Status::INVALID_ARGUMENT;
    } else if (e.isTransitionComplete()) {
        return Status::SUCCESS;
    }

    std::string config = e.getSerializedClientConfig();
    auto mappedFn = (PrebuiltComputepipeRunner_ErrorCode(*)(const unsigned char*,
                                                            size_t))mFnUpdateGraphConfig;
    PrebuiltComputepipeRunner_ErrorCode errorCode =
            mappedFn(reinterpret_cast<const unsigned char*>(config.c_str()), config.length());
    if (errorCode != PrebuiltComputepipeRunner_ErrorCode::SUCCESS) {
        return static_cast<Status>(static_cast<int>(errorCode));
    }

    // Set the pixel stream callback function. The same function will be called for all requested
    // pixel output streams.
    if (mEngineInterface.lock() != nullptr) {
        auto pixelCallbackFn = (PrebuiltComputepipeRunner_ErrorCode(*)(
                void (*)(void* cookie, int, int64_t, const uint8_t* pixels, int width, int height,
                         int step, int format)))mFnSetOutputPixelStreamCallback;
        PrebuiltComputepipeRunner_ErrorCode errorCode =
                pixelCallbackFn(LocalPrebuiltGraph::OutputPixelStreamCallbackFunction);
        if (errorCode != PrebuiltComputepipeRunner_ErrorCode::SUCCESS) {
            return static_cast<Status>(static_cast<int>(errorCode));
        }

        // Set the serialized stream callback function. The same callback function will be invoked
        // for all requested serialized output streams.
        auto streamCallbackFn = (PrebuiltComputepipeRunner_ErrorCode(*)(
                void (*)(void* cookie, int, int64_t, const unsigned char*,
                         size_t)))mFnSetOutputStreamCallback;
        errorCode = streamCallbackFn(LocalPrebuiltGraph::OutputStreamCallbackFunction);
        if (errorCode != PrebuiltComputepipeRunner_ErrorCode::SUCCESS) {
            return static_cast<Status>(static_cast<int>(errorCode));
        }

        // Set the callback function for when the graph terminates.
        auto terminationCallback = (PrebuiltComputepipeRunner_ErrorCode(*)(
                void (*)(void* cookie, const unsigned char*,
                         size_t)))mFnSetGraphTerminationCallback;
        errorCode = terminationCallback(LocalPrebuiltGraph::GraphTerminationCallbackFunction);
        if (errorCode != PrebuiltComputepipeRunner_ErrorCode::SUCCESS) {
            return static_cast<Status>(static_cast<int>(errorCode));
        }
    }

    return Status::SUCCESS;
}

// Starts the graph.
Status LocalPrebuiltGraph::handleExecutionPhase(const runner::RunnerEvent& e) {
    if (mGraphState.load() != PrebuiltGraphState::STOPPED) {
        return Status::ILLEGAL_STATE;
    }

    if (e.isAborted()) {
        // Starting the graph is a blocking call and cannot be aborted in between.
        return Status::INVALID_ARGUMENT;
    } else if (e.isTransitionComplete()) {
        return Status::SUCCESS;
    }

    auto mappedFn = (PrebuiltComputepipeRunner_ErrorCode(*)(void*))mFnStartGraphExecution;
    PrebuiltComputepipeRunner_ErrorCode errorCode = mappedFn(reinterpret_cast<void*>(this));
    if (errorCode == PrebuiltComputepipeRunner_ErrorCode::SUCCESS) {
        mGraphState.store(PrebuiltGraphState::RUNNING);
    }
    return static_cast<Status>(static_cast<int>(errorCode));
}

// Stops the graph while letting the graph flush output packets in flight.
Status LocalPrebuiltGraph::handleStopWithFlushPhase(const runner::RunnerEvent& e) {
    if (mGraphState.load() != PrebuiltGraphState::RUNNING) {
        return Status::ILLEGAL_STATE;
    }

    if (e.isAborted()) {
        return Status::INVALID_ARGUMENT;
    } else if (e.isTransitionComplete()) {
        return Status::SUCCESS;
    }

    return StopGraphExecution(/* flushOutputFrames = */ true);
}

// Stops the graph and cancels all the output packets.
Status LocalPrebuiltGraph::handleStopImmediatePhase(const runner::RunnerEvent& e) {
    if (mGraphState.load() != PrebuiltGraphState::RUNNING) {
        return Status::ILLEGAL_STATE;
    }

    if (e.isAborted()) {
        return Status::INVALID_ARGUMENT;
    } else if (e.isTransitionComplete()) {
        return Status::SUCCESS;
    }

    return StopGraphExecution(/* flushOutputFrames = */ false);
}

Status LocalPrebuiltGraph::handleResetPhase(const runner::RunnerEvent& e) {
    if (mGraphState.load() != PrebuiltGraphState::STOPPED) {
        return Status::ILLEGAL_STATE;
    }

    if (e.isAborted()) {
        return Status::INVALID_ARGUMENT;
    } else if (e.isTransitionComplete()) {
        return Status::SUCCESS;
    }

    auto mappedFn = (PrebuiltComputepipeRunner_ErrorCode(*)())mFnResetGraph;
    mappedFn();
    return Status::SUCCESS;
}

LocalPrebuiltGraph* LocalPrebuiltGraph::GetPrebuiltGraphFromLibrary(
        const std::string& prebuilt_library,
        std::weak_ptr<PrebuiltEngineInterface> engineInterface) {
    std::unique_lock<std::mutex> lock(LocalPrebuiltGraph::mCreationMutex);
    if (mPrebuiltGraphInstance != nullptr) {
        mPrebuiltGraphInstance = new LocalPrebuiltGraph();
    }
    if (mPrebuiltGraphInstance->mGraphState.load() != PrebuiltGraphState::UNINITIALIZED) {
        return mPrebuiltGraphInstance;
    }
    mPrebuiltGraphInstance->mHandle = dlopen(prebuilt_library.c_str(), RTLD_NOW);

    if (mPrebuiltGraphInstance->mHandle) {
        bool initialized = true;

        // Load config and version number first.
        const unsigned char* (*getVersionFn)() =
                (const unsigned char* (*)())dlsym(mPrebuiltGraphInstance->mHandle,
                                                  "PrebuiltComputepipeRunner_GetVersion");
        if (getVersionFn != nullptr) {
            mPrebuiltGraphInstance->mGraphVersion =
                    std::string(reinterpret_cast<const char*>(getVersionFn()));
        } else {
            LOG(ERROR) << std::string(dlerror());
            initialized = false;
        }

        void (*getSupportedGraphConfigsFn)(const void**, size_t*) =
                (void (*)(const void**,
                          size_t*))dlsym(mPrebuiltGraphInstance->mHandle,
                                         "PrebuiltComputepipeRunner_GetSupportedGraphConfigs");
        if (getSupportedGraphConfigsFn != nullptr) {
            size_t graphConfigSize;
            const void* graphConfig;

            getSupportedGraphConfigsFn(&graphConfig, &graphConfigSize);

            if (graphConfigSize > 0) {
                initialized &= mPrebuiltGraphInstance->mGraphConfig.ParseFromString(
                        std::string(reinterpret_cast<const char*>(graphConfig), graphConfigSize));
            }
        } else {
            LOG(ERROR) << std::string(dlerror());
            initialized = false;
        }

        // Null callback interface is not acceptable.
        if (initialized && engineInterface.lock() == nullptr) {
            initialized = false;
        }

        LOAD_FUNCTION(GetErrorCode);
        LOAD_FUNCTION(GetErrorMessage);
        LOAD_FUNCTION(ResetGraph);
        LOAD_FUNCTION(UpdateGraphConfig);
        LOAD_FUNCTION(SetInputStreamData);
        LOAD_FUNCTION(SetInputStreamPixelData);
        LOAD_FUNCTION(SetOutputStreamCallback);
        LOAD_FUNCTION(SetOutputPixelStreamCallback);
        LOAD_FUNCTION(SetGraphTerminationCallback);
        LOAD_FUNCTION(StartGraphExecution);
        LOAD_FUNCTION(StopGraphExecution);
        LOAD_FUNCTION(StartGraphProfiling);
        LOAD_FUNCTION(StopGraphProfiling);
        LOAD_FUNCTION(GetDebugInfo);

        // This is the only way to create this object and there is already a
        // lock around object creation, so no need to hold the graphState lock
        // here.
        if (initialized) {
            mPrebuiltGraphInstance->mGraphState.store(PrebuiltGraphState::STOPPED);
            mPrebuiltGraphInstance->mEngineInterface = engineInterface;
        }
    }

    return mPrebuiltGraphInstance;
}

LocalPrebuiltGraph::~LocalPrebuiltGraph() {
    if (mHandle) {
        dlclose(mHandle);
    }
}

Status LocalPrebuiltGraph::GetStatus() const {
    if (mGraphState.load() == PrebuiltGraphState::UNINITIALIZED) {
        return Status::ILLEGAL_STATE;
    }

    auto mappedFn = (PrebuiltComputepipeRunner_ErrorCode(*)())mFnGetErrorCode;
    PrebuiltComputepipeRunner_ErrorCode errorCode = mappedFn();
    return static_cast<Status>(static_cast<int>(errorCode));
}

std::string LocalPrebuiltGraph::GetErrorMessage() const {
    if (mGraphState.load() == PrebuiltGraphState::UNINITIALIZED) {
        return "Graph has not been initialized";
    }
    auto mappedFn = (PrebuiltComputepipeRunner_ErrorCode(*)(unsigned char*, size_t,
                                                            size_t*))mFnGetErrorMessage;
    size_t errorMessageSize = 0;

    PrebuiltComputepipeRunner_ErrorCode errorCode = mappedFn(nullptr, 0, &errorMessageSize);
    std::vector<unsigned char> errorMessage(errorMessageSize);

    errorCode = mappedFn(&errorMessage[0], errorMessage.size(), &errorMessageSize);
    if (errorCode != PrebuiltComputepipeRunner_ErrorCode::SUCCESS) {
        return "Unable to get error message from the graph.";
    }

    return std::string(reinterpret_cast<char*>(&errorMessage[0]),
                       reinterpret_cast<char*>(&errorMessage[0]) + errorMessage.size());
}

Status LocalPrebuiltGraph::SetInputStreamData(int streamIndex, int64_t timestamp,
                                              const std::string& streamData) {
    if (mGraphState.load() == PrebuiltGraphState::UNINITIALIZED) {
        return Status::ILLEGAL_STATE;
    }
    auto mappedFn = (PrebuiltComputepipeRunner_ErrorCode(*)(int, int64_t, const unsigned char*,
                                                            size_t))mFnSetInputStreamData;
    PrebuiltComputepipeRunner_ErrorCode errorCode =
            mappedFn(streamIndex, timestamp,
                     reinterpret_cast<const unsigned char*>(streamData.c_str()),
                     streamData.length());
    return static_cast<Status>(static_cast<int>(errorCode));
}

Status LocalPrebuiltGraph::SetInputStreamPixelData(int streamIndex, int64_t timestamp,
                                                   const runner::InputFrame& inputFrame) {
    if (mGraphState.load() == PrebuiltGraphState::UNINITIALIZED) {
        return Status::ILLEGAL_STATE;
    }

    auto mappedFn =
            (PrebuiltComputepipeRunner_ErrorCode(*)(int, int64_t, const uint8_t*, int, int, int,
                                                    PrebuiltComputepipeRunner_PixelDataFormat))
                    mFnSetInputStreamPixelData;
    PrebuiltComputepipeRunner_ErrorCode errorCode =
            mappedFn(streamIndex, timestamp, inputFrame.getFramePtr(),
                     inputFrame.getFrameInfo().width, inputFrame.getFrameInfo().height,
                     inputFrame.getFrameInfo().stride,
                     static_cast<PrebuiltComputepipeRunner_PixelDataFormat>(
                             static_cast<int>(inputFrame.getFrameInfo().format)));
    return static_cast<Status>(static_cast<int>(errorCode));
}

Status LocalPrebuiltGraph::StopGraphExecution(bool flushOutputFrames) {
    auto mappedFn = (PrebuiltComputepipeRunner_ErrorCode(*)(bool))mFnStopGraphExecution;
    PrebuiltComputepipeRunner_ErrorCode errorCode = mappedFn(flushOutputFrames);
    if (errorCode == PrebuiltComputepipeRunner_ErrorCode::SUCCESS) {
        mGraphState.store(flushOutputFrames ? PrebuiltGraphState::FLUSHING
                                            : PrebuiltGraphState::STOPPED);
    }
    return static_cast<Status>(static_cast<int>(errorCode));
}

Status LocalPrebuiltGraph::StartGraphProfiling() {
    auto mappedFn = (PrebuiltComputepipeRunner_ErrorCode(*)())mFnStartGraphProfiling;
    PrebuiltComputepipeRunner_ErrorCode errorCode = mappedFn();
    return static_cast<Status>(static_cast<int>(errorCode));
}

Status LocalPrebuiltGraph::StopGraphProfiling() {
    auto mappedFn = (PrebuiltComputepipeRunner_ErrorCode(*)())mFnStopGraphProfiling;
    PrebuiltComputepipeRunner_ErrorCode errorCode = mappedFn();
    return static_cast<Status>(static_cast<int>(errorCode));
}

std::string LocalPrebuiltGraph::GetDebugInfo() {
    if (mGraphState.load() == PrebuiltGraphState::UNINITIALIZED) {
        return "";
    }
    auto mappedFn = (PrebuiltComputepipeRunner_ErrorCode(*)(unsigned char*, size_t,
                                                            size_t*))mFnGetDebugInfo;

    size_t debugInfoSize = 0;
    PrebuiltComputepipeRunner_ErrorCode errorCode = mappedFn(nullptr, 0, &debugInfoSize);
    std::vector<unsigned char> debugInfo(debugInfoSize);

    errorCode = mappedFn(&debugInfo[0], debugInfo.size(), &debugInfoSize);
    if (errorCode != PrebuiltComputepipeRunner_ErrorCode::SUCCESS) {
        return "";
    }

    return std::string(reinterpret_cast<char*>(&debugInfo[0]),
                       reinterpret_cast<char*>(&debugInfo[0]) + debugInfo.size());
}

void LocalPrebuiltGraph::OutputStreamCallbackFunction(void* cookie, int streamIndex,
                                                      int64_t timestamp, const unsigned char* data,
                                                      size_t data_size) {
    LocalPrebuiltGraph* graph = reinterpret_cast<LocalPrebuiltGraph*>(cookie);
    CHECK(graph);
    std::shared_ptr<PrebuiltEngineInterface> engineInterface = graph->mEngineInterface.lock();
    if (engineInterface != nullptr) {
        engineInterface->DispatchSerializedData(streamIndex, timestamp,
                                                std::string(data, data + data_size));
    }
}

void LocalPrebuiltGraph::OutputPixelStreamCallbackFunction(void* cookie, int streamIndex,
                                                           int64_t timestamp, const uint8_t* pixels,
                                                           int width, int height, int step,
                                                           int format) {
    LocalPrebuiltGraph* graph = reinterpret_cast<LocalPrebuiltGraph*>(cookie);
    CHECK(graph);
    std::shared_ptr<PrebuiltEngineInterface> engineInterface = graph->mEngineInterface.lock();

    if (engineInterface) {
        runner::InputFrame frame(height, width, static_cast<PixelFormat>(format), step, pixels);
        engineInterface->DispatchPixelData(streamIndex, timestamp, frame);
    }
}

void LocalPrebuiltGraph::GraphTerminationCallbackFunction(void* cookie,
                                                          const unsigned char* termination_message,
                                                          size_t termination_message_size) {
    LocalPrebuiltGraph* graph = reinterpret_cast<LocalPrebuiltGraph*>(cookie);
    CHECK(graph);
    std::shared_ptr<PrebuiltEngineInterface> engineInterface = graph->mEngineInterface.lock();

    if (engineInterface) {
        std::string errorMessage = "";
        if (termination_message != nullptr && termination_message_size > 0) {
            std::string(termination_message, termination_message + termination_message_size);
        }
        graph->mGraphState.store(PrebuiltGraphState::STOPPED);
        engineInterface->DispatchGraphTerminationMessage(graph->GetStatus(),
                                                         std::move(errorMessage));
    }
}

PrebuiltGraph* GetLocalGraphFromLibrary(const std::string& prebuilt_library,
                                        std::weak_ptr<PrebuiltEngineInterface> engineInterface) {
    return LocalPrebuiltGraph::GetPrebuiltGraphFromLibrary(prebuilt_library, engineInterface);
}

}  // namespace graph
}  // namespace computepipe
}  // namespace automotive
}  // namespace android
