// 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 "GrpcGraph.h"

#include <cstdlib>

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

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

namespace android {
namespace automotive {
namespace computepipe {
namespace graph {
namespace {
constexpr int64_t kRpcDeadlineMilliseconds = 100;

template <class ResponseType, class RpcType>
std::pair<Status, std::string> FinishRpcAndGetResult(
        ::grpc::ClientAsyncResponseReader<RpcType>* rpc, ::grpc::CompletionQueue* cq,
        ResponseType* response) {
    int random_tag = rand();
    ::grpc::Status grpcStatus;
    rpc->Finish(response, &grpcStatus, reinterpret_cast<void*>(random_tag));
    bool ok = false;
    void* got_tag;
    if (!cq->Next(&got_tag, &ok)) {
        LOG(ERROR) << "Unexpected shutdown of the completion queue";
        return std::pair(Status::FATAL_ERROR, "Unexpected shutdown of the completion queue");
    }

    if (!ok) {
        LOG(ERROR) << "Unable to complete RPC request";
        return std::pair(Status::FATAL_ERROR, "Unable to complete RPC request");
    }

    CHECK_EQ(got_tag, reinterpret_cast<void*>(random_tag));
    if (!grpcStatus.ok()) {
        std::string error_message =
                std::string("Grpc failed with error: ") + grpcStatus.error_message();
        LOG(ERROR) << error_message;
        return std::pair(Status::FATAL_ERROR, std::move(error_message));
    }

    return std::pair(Status::SUCCESS, std::string(""));
}

}  // namespace

GrpcGraph::~GrpcGraph() {
    mStreamSetObserver.reset();
}

PrebuiltGraphState GrpcGraph::GetGraphState() const {
    std::lock_guard lock(mLock);
    return mGraphState;
}

Status GrpcGraph::GetStatus() const {
    std::lock_guard lock(mLock);
    return mStatus;
}

std::string GrpcGraph::GetErrorMessage() const {
    std::lock_guard lock(mLock);
    return mErrorMessage;
}

Status GrpcGraph::initialize(const std::string& address,
                             std::weak_ptr<PrebuiltEngineInterface> engineInterface) {
    std::shared_ptr<::grpc::ChannelCredentials> creds = ::grpc::InsecureChannelCredentials();
    std::shared_ptr<::grpc::Channel> channel = ::grpc::CreateChannel(address, creds);
    mGraphStub = proto::GrpcGraphService::NewStub(channel);
    mEngineInterface = engineInterface;

    ::grpc::ClientContext context;
    context.set_deadline(std::chrono::system_clock::now() +
                         std::chrono::milliseconds(kRpcDeadlineMilliseconds));
    ::grpc::CompletionQueue cq;

    proto::GraphOptionsRequest getGraphOptionsRequest;
    std::unique_ptr<::grpc::ClientAsyncResponseReader<proto::GraphOptionsResponse>> rpc(
            mGraphStub->AsyncGetGraphOptions(&context, getGraphOptionsRequest, &cq));

    proto::GraphOptionsResponse response;
    auto [mStatus, mErrorMessage] = FinishRpcAndGetResult(rpc.get(), &cq, &response);

    if (mStatus != Status::SUCCESS) {
        LOG(ERROR) << "Failed to get graph options: " << mErrorMessage;
        return Status::FATAL_ERROR;
    }

    std::string serialized_options = response.serialized_options();
    if (!mGraphConfig.ParseFromString(serialized_options)) {
        mErrorMessage = "Failed to parse graph options";
        LOG(ERROR) << "Failed to parse graph options";
        return Status::FATAL_ERROR;
    }

    mGraphState = PrebuiltGraphState::STOPPED;
    return Status::SUCCESS;
}

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

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

    ::grpc::ClientContext context;
    context.set_deadline(std::chrono::system_clock::now() +
                         std::chrono::milliseconds(kRpcDeadlineMilliseconds));
    ::grpc::CompletionQueue cq;

    std::string serializedConfig = e.getSerializedClientConfig();
    proto::SetGraphConfigRequest setGraphConfigRequest;
    setGraphConfigRequest.set_serialized_config(std::move(serializedConfig));

    std::unique_ptr<::grpc::ClientAsyncResponseReader<proto::StatusResponse>> rpc(
            mGraphStub->AsyncSetGraphConfig(&context, setGraphConfigRequest, &cq));

    proto::StatusResponse response;
    auto [mStatus, mErrorMessage] = FinishRpcAndGetResult(rpc.get(), &cq, &response);
    if (mStatus != Status::SUCCESS) {
        LOG(ERROR) << "Rpc failed while trying to set configuration";
        return mStatus;
    }

    if (response.code() != proto::RemoteGraphStatusCode::SUCCESS) {
        LOG(ERROR) << "Failed to cofngure remote graph. " << response.message();
    }

    mStatus = static_cast<Status>(static_cast<int>(response.code()));
    mErrorMessage = response.message();

    mStreamSetObserver = std::make_unique<StreamSetObserver>(e, this);

    return mStatus;
}

// Starts the graph.
Status GrpcGraph::handleExecutionPhase(const runner::RunnerEvent& e) {
    std::lock_guard lock(mLock);
    if (mGraphState != PrebuiltGraphState::STOPPED) {
        mStatus = Status::ILLEGAL_STATE;
        return mStatus;
    }

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

    // Start observing the output streams
    mStatus = mStreamSetObserver->startObservingStreams();
    if (mStatus != Status::SUCCESS) {
        mErrorMessage = "Failed to observe output streams";
        return mStatus;
    }

    ::grpc::ClientContext context;
    context.set_deadline(std::chrono::system_clock::now() +
                         std::chrono::milliseconds(kRpcDeadlineMilliseconds));

    proto::StartGraphExecutionRequest startExecutionRequest;
    ::grpc::CompletionQueue cq;
    std::unique_ptr<::grpc::ClientAsyncResponseReader<proto::StatusResponse>> rpc(
            mGraphStub->AsyncStartGraphExecution(&context, startExecutionRequest, &cq));

    proto::StatusResponse response;
    auto [mStatus, mErrorMessage] = FinishRpcAndGetResult(rpc.get(), &cq, &response);
    if (mStatus != Status::SUCCESS) {
        LOG(ERROR) << "Failed to start graph execution";
        return mStatus;
    }

    mStatus = static_cast<Status>(static_cast<int>(response.code()));
    mErrorMessage = response.message();

    if (mStatus == Status::SUCCESS) {
        mGraphState = PrebuiltGraphState::RUNNING;
    }

    return mStatus;
}

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

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

    ::grpc::ClientContext context;
    context.set_deadline(std::chrono::system_clock::now() +
                         std::chrono::milliseconds(kRpcDeadlineMilliseconds));

    proto::StopGraphExecutionRequest stopExecutionRequest;
    stopExecutionRequest.set_stop_immediate(false);
    ::grpc::CompletionQueue cq;
    std::unique_ptr<::grpc::ClientAsyncResponseReader<proto::StatusResponse>> rpc(
            mGraphStub->AsyncStopGraphExecution(&context, stopExecutionRequest, &cq));

    proto::StatusResponse response;
    auto [mStatus, mErrorMessage] = FinishRpcAndGetResult(rpc.get(), &cq, &response);
    if (mStatus != Status::SUCCESS) {
        LOG(ERROR) << "Failed to stop graph execution";
        return Status::FATAL_ERROR;
    }

    // Stop observing streams immendiately.
    mStreamSetObserver->stopObservingStreams(false);

    mStatus = static_cast<Status>(static_cast<int>(response.code()));
    mErrorMessage = response.message();

    if (mStatus == Status::SUCCESS) {
        mGraphState = PrebuiltGraphState::FLUSHING;
    }

    return mStatus;
}

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

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

    ::grpc::ClientContext context;
    context.set_deadline(std::chrono::system_clock::now() +
                         std::chrono::milliseconds(kRpcDeadlineMilliseconds));

    proto::StopGraphExecutionRequest stopExecutionRequest;
    stopExecutionRequest.set_stop_immediate(true);
    ::grpc::CompletionQueue cq;
    std::unique_ptr<::grpc::ClientAsyncResponseReader<proto::StatusResponse>> rpc(
            mGraphStub->AsyncStopGraphExecution(&context, stopExecutionRequest, &cq));

    proto::StatusResponse response;
    auto [mStatus, mErrorMessage] = FinishRpcAndGetResult(rpc.get(), &cq, &response);
    if (mStatus != Status::SUCCESS) {
        LOG(ERROR) << "Failed to stop graph execution";
        return Status::FATAL_ERROR;
    }

    mStatus = static_cast<Status>(static_cast<int>(response.code()));
    mErrorMessage = response.message();

    // Stop observing streams immendiately.
    mStreamSetObserver->stopObservingStreams(true);

    if (mStatus == Status::SUCCESS) {
        mGraphState = PrebuiltGraphState::STOPPED;
    }
    return mStatus;
}

Status GrpcGraph::handleResetPhase(const runner::RunnerEvent& e) {
    std::lock_guard lock(mLock);
    if (mGraphState != PrebuiltGraphState::STOPPED) {
        return Status::ILLEGAL_STATE;
    }

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

    ::grpc::ClientContext context;
    context.set_deadline(std::chrono::system_clock::now() +
                         std::chrono::milliseconds(kRpcDeadlineMilliseconds));

    proto::ResetGraphRequest resetGraphRequest;
    ::grpc::CompletionQueue cq;
    std::unique_ptr<::grpc::ClientAsyncResponseReader<proto::StatusResponse>> rpc(
            mGraphStub->AsyncResetGraph(&context, resetGraphRequest, &cq));

    proto::StatusResponse response;
    auto [mStatus, mErrorMessage] = FinishRpcAndGetResult(rpc.get(), &cq, &response);
    if (mStatus != Status::SUCCESS) {
        LOG(ERROR) << "Failed to stop graph execution";
        return Status::FATAL_ERROR;
    }

    mStatus = static_cast<Status>(static_cast<int>(response.code()));
    mErrorMessage = response.message();
    mStreamSetObserver.reset();

    return mStatus;
}

Status GrpcGraph::SetInputStreamData(int /*streamIndex*/, int64_t /*timestamp*/,
                                     const std::string& /*streamData*/) {
    LOG(ERROR) << "Cannot set input stream for remote graphs";
    return Status::FATAL_ERROR;
}

Status GrpcGraph::SetInputStreamPixelData(int /*streamIndex*/, int64_t /*timestamp*/,
                                          const runner::InputFrame& /*inputFrame*/) {
    LOG(ERROR) << "Cannot set input streams for remote graphs";
    return Status::FATAL_ERROR;
}

Status GrpcGraph::StartGraphProfiling() {
    std::lock_guard lock(mLock);
    if (mGraphState != PrebuiltGraphState::RUNNING) {
        return Status::ILLEGAL_STATE;
    }

    ::grpc::ClientContext context;
    context.set_deadline(std::chrono::system_clock::now() +
                         std::chrono::milliseconds(kRpcDeadlineMilliseconds));

    proto::StartGraphProfilingRequest startProfilingRequest;
    ::grpc::CompletionQueue cq;
    std::unique_ptr<::grpc::ClientAsyncResponseReader<proto::StatusResponse>> rpc(
            mGraphStub->AsyncStartGraphProfiling(&context, startProfilingRequest, &cq));

    proto::StatusResponse response;
    auto [mStatus, mErrorMessage] = FinishRpcAndGetResult(rpc.get(), &cq, &response);
    if (mStatus != Status::SUCCESS) {
        LOG(ERROR) << "Failed to start graph profiling";
        return Status::FATAL_ERROR;
    }

    mStatus = static_cast<Status>(static_cast<int>(response.code()));
    mErrorMessage = response.message();

    return mStatus;
}

Status GrpcGraph::StopGraphProfiling() {
    // Stopping profiling after graph has already stopped can be a no-op
    ::grpc::ClientContext context;
    context.set_deadline(std::chrono::system_clock::now() +
                         std::chrono::milliseconds(kRpcDeadlineMilliseconds));

    proto::StopGraphProfilingRequest stopProfilingRequest;
    ::grpc::CompletionQueue cq;
    std::unique_ptr<::grpc::ClientAsyncResponseReader<proto::StatusResponse>> rpc(
            mGraphStub->AsyncStopGraphProfiling(&context, stopProfilingRequest, &cq));

    proto::StatusResponse response;
    auto [mStatus, mErrorMessage] = FinishRpcAndGetResult(rpc.get(), &cq, &response);
    if (mStatus != Status::SUCCESS) {
        LOG(ERROR) << "Failed to stop graph profiling";
        return Status::FATAL_ERROR;
    }

    mStatus = static_cast<Status>(static_cast<int>(response.code()));
    mErrorMessage = response.message();

    return mStatus;
}

std::string GrpcGraph::GetDebugInfo() {
    ::grpc::ClientContext context;
    context.set_deadline(std::chrono::system_clock::now() +
                         std::chrono::milliseconds(kRpcDeadlineMilliseconds));

    proto::ProfilingDataRequest profilingDataRequest;
    ::grpc::CompletionQueue cq;
    std::unique_ptr<::grpc::ClientAsyncResponseReader<proto::ProfilingDataResponse>> rpc(
            mGraphStub->AsyncGetProfilingData(&context, profilingDataRequest, &cq));

    proto::ProfilingDataResponse response;
    auto [mStatus, mErrorMessage] = FinishRpcAndGetResult(rpc.get(), &cq, &response);
    if (mStatus != Status::SUCCESS) {
        LOG(ERROR) << "Failed to get profiling info";
        return "";
    }

    return response.data();
}

void GrpcGraph::dispatchPixelData(int streamId, int64_t timestamp_us,
                                  const runner::InputFrame& frame) {
    std::shared_ptr<PrebuiltEngineInterface> engineInterface = mEngineInterface.lock();
    if (engineInterface) {
        return engineInterface->DispatchPixelData(streamId, timestamp_us, frame);
    }
}

void GrpcGraph::dispatchSerializedData(int streamId, int64_t timestamp_us,
                                       std::string&& serialized_data) {
    std::shared_ptr<PrebuiltEngineInterface> engineInterface = mEngineInterface.lock();
    if (engineInterface) {
        return engineInterface->DispatchSerializedData(streamId, timestamp_us,
                                                       std::move(serialized_data));
    }
}

void GrpcGraph::dispatchGraphTerminationMessage(Status status, std::string&& errorMessage) {
    std::lock_guard lock(mLock);
    mErrorMessage = std::move(errorMessage);
    mStatus = status;
    mGraphState = PrebuiltGraphState::STOPPED;
    std::shared_ptr<PrebuiltEngineInterface> engineInterface = mEngineInterface.lock();
    if (engineInterface) {
        std::string errorMessageTmp = mErrorMessage;
        engineInterface->DispatchGraphTerminationMessage(mStatus, std::move(errorMessageTmp));
    }
}

std::unique_ptr<PrebuiltGraph> GetRemoteGraphFromAddress(
        const std::string& address, std::weak_ptr<PrebuiltEngineInterface> engineInterface) {
    auto prebuiltGraph = std::make_unique<GrpcGraph>();
    Status status = prebuiltGraph->initialize(address, engineInterface);
    if (status != Status::SUCCESS) {
        return nullptr;
    }

    return prebuiltGraph;
}

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