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

#include "InterfaceImpl.h"

#include "OutputConfig.pb.h"
#include "PacketDescriptor.pb.h"
#include "PipeOptionsConverter.h"

#define LOG_TAG "RunnerIpcInterface"
#include <aidl/android/automotive/computepipe/runner/PacketDescriptor.h>
#include <aidl/android/automotive/computepipe/runner/PacketDescriptorPacketType.h>
#include <android-base/logging.h>
#include <android/binder_auto_utils.h>

namespace android {
namespace automotive {
namespace computepipe {
namespace runner_utils {
namespace {

using ::aidl::android::automotive::computepipe::runner::IPipeStateCallback;
using ::aidl::android::automotive::computepipe::runner::IPipeStream;
using ::aidl::android::automotive::computepipe::runner::PacketDescriptor;
using ::aidl::android::automotive::computepipe::runner::PacketDescriptorPacketType;
using ::aidl::android::automotive::computepipe::runner::PipeDescriptor;
using ::aidl::android::automotive::computepipe::runner::PipeState;
using ::ndk::ScopedAStatus;

ScopedAStatus ToNdkStatus(Status status) {
    switch (status) {
        case SUCCESS:
            return ScopedAStatus::ok();
        case INTERNAL_ERROR:
            return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
        case INVALID_ARGUMENT:
            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
        case FATAL_ERROR:
        default:
            return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
    }
}

PipeState ToAidlState(GraphState state) {
    switch (state) {
        case RESET:
            return PipeState::RESET;
        case CONFIG_DONE:
            return PipeState::CONFIG_DONE;
        case RUNNING:
            return PipeState::RUNNING;
        case DONE:
            return PipeState::DONE;
        case ERR_HALT:
        default:
            return PipeState::ERR_HALT;
    }
}

void deathNotifier(void* cookie) {
    InterfaceImpl* iface = static_cast<InterfaceImpl*>(cookie);
    iface->clientDied();
}

Status ToAidlPacketType(proto::PacketType type, PacketDescriptorPacketType& outType) {
    switch (type) {
        case proto::SEMANTIC_DATA:
            outType = PacketDescriptorPacketType::SEMANTIC_DATA;
            return Status::SUCCESS;
        case proto::PIXEL_DATA:
            outType = PacketDescriptorPacketType::PIXEL_DATA;
            return Status::SUCCESS;
        default:
            LOG(ERROR) << "unknown packet type " << type;
            return Status::INVALID_ARGUMENT;
    }
}

}  // namespace

Status InterfaceImpl::DispatchSemanticData(int32_t streamId,
                                           const std::shared_ptr<MemHandle>& packetHandle) {
    PacketDescriptor desc;

    if (mPacketHandlers.find(streamId) == mPacketHandlers.end()) {
        LOG(ERROR) << "Bad streamId";
        return Status::INVALID_ARGUMENT;
    }
    Status status = ToAidlPacketType(packetHandle->getType(), desc.type);
    if (status != SUCCESS) {
        return status;
    }
    desc.data = packetHandle->getData();
    desc.size = packetHandle->getSize();
    if (static_cast<int32_t>(desc.data.size()) != desc.size) {
        LOG(ERROR) << "mismatch in char data size and reported size";
        return Status::INVALID_ARGUMENT;
    }
    desc.sourceTimeStampMillis = packetHandle->getTimeStamp();
    desc.bufId = 0;
    ScopedAStatus ret = mPacketHandlers[streamId]->deliverPacket(desc);
    if (!ret.isOk()) {
        LOG(ERROR) << "Dropping Semantic packet due to error ";
    }
    return Status::SUCCESS;
}

// Thread-safe function to deliver new packets to client.
Status InterfaceImpl::newPacketNotification(int32_t streamId,
                                            const std::shared_ptr<MemHandle>& packetHandle) {
    // TODO(146464279) implement.
    if (!packetHandle) {
        LOG(ERROR) << "invalid packetHandle";
        return Status::INVALID_ARGUMENT;
    }
    proto::PacketType packetType = packetHandle->getType();
    switch (packetType) {
        case proto::SEMANTIC_DATA:
            return DispatchSemanticData(streamId, packetHandle);
        default:
            LOG(ERROR) << "Unsupported packet type " << packetHandle->getType();
            return Status::INVALID_ARGUMENT;
    }
    return Status::SUCCESS;
}

Status InterfaceImpl::stateUpdateNotification(const GraphState newState) {
    (void)mClientStateChangeCallback->handleState(ToAidlState(newState));
    return Status::SUCCESS;
}

ScopedAStatus InterfaceImpl::getPipeDescriptor(PipeDescriptor* _aidl_return) {
    if (_aidl_return == nullptr) {
        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
    }
    *_aidl_return = OptionsToPipeDesciptor(mGraphOptions);
    return ScopedAStatus::ok();
}

ScopedAStatus InterfaceImpl::setPipeInputSource(int32_t configId) {
    if (!isClientInitDone()) {
        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
    }

    proto::ConfigurationCommand configurationCommand;
    configurationCommand.mutable_set_input_source()->set_source_id(configId);

    Status status = mRunnerInterfaceCallbacks.mProcessConfigurationCommand(configurationCommand);
    return ToNdkStatus(status);
}

ScopedAStatus InterfaceImpl::setPipeOffloadOptions(int32_t configId) {
    if (!isClientInitDone()) {
        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
    }

    proto::ConfigurationCommand configurationCommand;
    configurationCommand.mutable_set_offload_offload()->set_offload_option_id(configId);

    Status status = mRunnerInterfaceCallbacks.mProcessConfigurationCommand(configurationCommand);
    return ToNdkStatus(status);
}

ScopedAStatus InterfaceImpl::setPipeTermination(int32_t configId) {
    if (!isClientInitDone()) {
        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
    }

    proto::ConfigurationCommand configurationCommand;
    configurationCommand.mutable_set_termination_option()->set_termination_option_id(configId);

    Status status = mRunnerInterfaceCallbacks.mProcessConfigurationCommand(configurationCommand);
    return ToNdkStatus(status);
}

ScopedAStatus InterfaceImpl::init(const std::shared_ptr<IPipeStateCallback>& stateCb) {
    if (isClientInitDone()) {
        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
    }

    AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(&deathNotifier);
    AIBinder_linkToDeath(stateCb->asBinder().get(), recipient, this);

    mClientStateChangeCallback = stateCb;
    return ScopedAStatus::ok();
}

bool InterfaceImpl::isClientInitDone() {
    if (mClientStateChangeCallback == nullptr) {
        return false;
    }
    return true;
}

void InterfaceImpl::clientDied() {
    LOG(INFO) << "Client has died";
    releaseRunner();
}

ScopedAStatus InterfaceImpl::setPipeOutputConfig(int32_t streamId, int32_t maxInFlightCount,
                                                 const std::shared_ptr<IPipeStream>& handler) {
    if (!isClientInitDone()) {
        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
    }

    if (mPacketHandlers.find(streamId) != mPacketHandlers.end()) {
        LOG(INFO) << "Handler for stream id " << streamId
                  << " has already"
                     " been registered.";
        return ToNdkStatus(INVALID_ARGUMENT);
    }

    mPacketHandlers.insert(std::pair<int, std::shared_ptr<IPipeStream>>(streamId, handler));

    proto::ConfigurationCommand configurationCommand;
    configurationCommand.mutable_set_output_stream()->set_stream_id(streamId);
    configurationCommand.mutable_set_output_stream()->set_max_inflight_packets_count(
        maxInFlightCount);
    Status status = mRunnerInterfaceCallbacks.mProcessConfigurationCommand(configurationCommand);

    if (status != SUCCESS) {
        LOG(INFO) << "Failed to register handler for stream id " << streamId;
        mPacketHandlers.erase(streamId);
    }
    return ToNdkStatus(status);
}

ScopedAStatus InterfaceImpl::applyPipeConfigs() {
    if (!isClientInitDone()) {
        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
    }

    proto::ControlCommand controlCommand;
    *controlCommand.mutable_apply_configs() = proto::ApplyConfigs();

    Status status = mRunnerInterfaceCallbacks.mProcessControlCommand(controlCommand);
    return ToNdkStatus(status);
}

ScopedAStatus InterfaceImpl::startPipe() {
    proto::ControlCommand controlCommand;
    *controlCommand.mutable_start_graph() = proto::StartGraph();

    Status status = mRunnerInterfaceCallbacks.mProcessControlCommand(controlCommand);
    return ToNdkStatus(status);
}

ScopedAStatus InterfaceImpl::stopPipe() {
    proto::ControlCommand controlCommand;
    *controlCommand.mutable_stop_graph() = proto::StopGraph();

    Status status = mRunnerInterfaceCallbacks.mProcessControlCommand(controlCommand);
    return ToNdkStatus(status);
}

ScopedAStatus InterfaceImpl::doneWithPacket(int32_t id) {
    // TODO(146464279) implement.
    return ScopedAStatus::ok();
}

ndk::ScopedAStatus InterfaceImpl::getPipeDebugger(
    std::shared_ptr<aidl::android::automotive::computepipe::runner::IPipeDebugger>* _aidl_return) {
    // TODO(146464281) implement.
    return ScopedAStatus::ok();
}

ndk::ScopedAStatus InterfaceImpl::releaseRunner() {
    proto::ControlCommand controlCommand;
    *controlCommand.mutable_death_notification() = proto::DeathNotification();

    Status status = mRunnerInterfaceCallbacks.mProcessControlCommand(controlCommand);

    mClientStateChangeCallback = nullptr;
    mPacketHandlers.clear();
    return ToNdkStatus(status);
}

}  // namespace runner_utils
}  // namespace computepipe
}  // namespace automotive
}  // namespace android
