#include "v1_1/foo_stub.h"
#include <hdf_base.h>
#include <hdf_core_log.h>
#include <hdi_support.h>
#include <securec.h>
#include <string_ex.h>

#define HDF_LOG_TAG    foo_stub

int32_t OHOS::HDI::Foo::V1_1::FooStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option)
{
    switch (code) {
        case CMD_FOO_GET_VERSION:
            return FooStubGetVersion(data, reply, option);
        case CMD_FOO_PING:
            return FooStubPing_4(data, reply, option);
        case CMD_FOO_GET_DATA:
            return FooStubGetData_5(data, reply, option);
        case CMD_FOO_PING:
            return FooStubPing(data, reply, option);
        case CMD_FOO_GET_DATA:
            return FooStubGetData(data, reply, option);
        case CMD_FOO_INFO_TEST:
            return FooStubInfoTest(data, reply, option);
        default: {
            HDF_LOGE("%{public}s: cmd %{public}d is not supported", __func__, code);
            return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
        }
    }
}

int32_t OHOS::HDI::Foo::V1_1::FooStub::FooStubPing_4(MessageParcel& fooData, MessageParcel& fooReply, MessageOption& fooOption)

int32_t OHOS::HDI::Foo::V1_1::FooStub::FooStubGetData_5(MessageParcel& fooData, MessageParcel& fooReply, MessageOption& fooOption)

int32_t OHOS::HDI::Foo::V1_1::FooStub::FooStubPing(MessageParcel& fooData, MessageParcel& fooReply, MessageOption& fooOption)

int32_t OHOS::HDI::Foo::V1_1::FooStub::FooStubGetData(MessageParcel& fooData, MessageParcel& fooReply, MessageOption& fooOption)

int32_t OHOS::HDI::Foo::V1_1::FooStub::FooStubInfoTest(MessageParcel& fooData, MessageParcel& fooReply, MessageOption& fooOption)

int32_t OHOS::HDI::Foo::V1_1::FooStub::FooStubGetVersion(MessageParcel& fooData, MessageParcel& fooReply, MessageOption& fooOption)

int32_t OHOS::HDI::Foo::V1_1::FooStub::FooStubPing_4_(MessageParcel& fooData, MessageParcel& fooReply, MessageOption& fooOption, sptr<OHOS::HDI::Foo::V1_1::IFoo> impl)
{
    if (fooData.ReadInterfaceToken() != OHOS::HDI::Foo::V1_1::IFoo::GetDescriptor()) {
        HDF_LOGE("%{public}s: interface token check failed!", __func__);
        return HDF_ERR_INVALID_PARAM;
    }

    bool fooMemSet = false;
    if (!fooData.ReadBool(fooMemSet)) {
        HDF_LOGE("%{public}s: failed to read fooMemSet", __func__);
        return HDF_ERR_INVALID_PARAM;
    }
    const char* sendMsgCp = fooData.ReadCString();
    if (sendMsgCp == nullptr) {
        HDF_LOGE("%{public}s: read sendMsg failed", __func__);
        return HDF_ERR_INVALID_PARAM;
    }
    std::string sendMsg = sendMsgCp;

    std::string recvMsg;
    if (fooMemSet) {
        uint32_t capacity = 0;
        if (!fooData.ReadUint32(capacity)) {
            HDF_LOGE("%{public}s: failed to read capacity", __func__);
            return HDF_ERR_INVALID_PARAM;
        }
        HDI_CHECK_VALUE_RETURN(capacity, >, HDI_BUFF_MAX_SIZE / sizeof(char), HDF_ERR_INVALID_PARAM);
        recvMsg.reserve(capacity);
    }

    int32_t code = 0;
    if (!fooData.ReadInt32(code)) {
        HDF_LOGE("%{public}s: read code failed!", __func__);
        return HDF_ERR_INVALID_PARAM;
    }

    if (impl == nullptr) {
        HDF_LOGE("%{public}s: impl is nullptr!", __func__);
        return HDF_ERR_INVALID_PARAM;
    }

    int32_t fooRet = impl->Ping(sendMsg, recvMsg, code);
    if (fooRet != HDF_SUCCESS) {
        HDF_LOGE("%{public}s failed, error code is %{public}d", __func__, fooRet);
        return fooRet;
    }

    if (!fooReply.WriteCString(recvMsg.c_str())) {
        HDF_LOGE("%{public}s: write recvMsg failed!", __func__);
        return HDF_ERR_INVALID_PARAM;
    }

    return fooRet;
}

int32_t OHOS::HDI::Foo::V1_1::FooStub::FooStubGetData_5_(MessageParcel& fooData, MessageParcel& fooReply, MessageOption& fooOption, sptr<OHOS::HDI::Foo::V1_1::IFoo> impl)