#pragma once
/***********************************************************
 Copyright (c) 2019 Qualcomm Technologies, Inc.
 All Rights Reserved.
 Confidential and Proprietary - Qualcomm Technologies, Inc.
************************************************************/

/**
 * Example interface showcasing what SMCInvoke can do.
 */

/** @cond */

/** MINK IDL allows us to define structs which can be passed
    directly to function calls as parameters. Here we define
    a results struct; which we can use to return both the
    result of the current addition and the total sum from the
    context to the caller. */

// AUTOGENERATED FILE: DO NOT EDIT

#include <cstdint>
#include "object.h"
#include "proxy_base.hpp"

struct additionStruct {
    uint32_t int1;
    uint32_t int2;
};

struct statusStruct {
    uint32_t total;
    uint32_t totalSaturated;
    uint32_t callCount;
    int32_t lastCall;
    uint32_t lastResult;
    uint32_t resultSaturated;
    uint32_t overflowFlag;
};

class IIAdder {
   public:
    static const uint32_t OVERFLOW_TRUE = UINT32_C(1);
    static const uint32_t OVERFLOW_FALSE = UINT32_C(0);

    virtual ~IIAdder() {}

    virtual int32_t add(uint32_t val1_val, int32_t val2_val, uint32_t* result_ptr) = 0;
    virtual int32_t addArray(const uint32_t* intArray_ptr, size_t intArray_len, uint32_t* result_ptr) = 0;
    virtual int32_t addStruct(const additionStruct &inStruct_ref, uint32_t* result_ptr) = 0;
    virtual int32_t getStatus(statusStruct &status_ref) = 0;

   protected:
    static const ObjectOp OP_add = 0;
    static const ObjectOp OP_addArray = 1;
    static const ObjectOp OP_addStruct = 2;
    static const ObjectOp OP_getStatus = 3;
};

class IAdder : public IIAdder, public ProxyBase {
   public:
    IAdder() {}
    IAdder(Object impl) : ProxyBase(impl) {}
    virtual ~IAdder() {}

    virtual int32_t add(uint32_t val1_val, int32_t val2_val, uint32_t* result_ptr) {
        ObjectArg a[2]={{{0,0}}};
        struct s1 {
            uint32_t m_val1;
            int32_t m_val2;
        } i;
        a[0].b = (ObjectBuf) {&i, 8};
        i.m_val1 = val1_val;
        i.m_val2 = val2_val;
        a[1].b = (ObjectBuf) {result_ptr, sizeof(uint32_t)};

        return invoke(OP_add, a, ObjectCounts_pack(1, 1, 0, 0));
    }

    virtual int32_t addArray(const uint32_t* intArray_ptr, size_t intArray_len, uint32_t* result_ptr) {
        ObjectArg a[2]={{{0,0}}};
        a[0].bi = (ObjectBufIn) {intArray_ptr, intArray_len * sizeof(uint32_t)};
        a[1].b = (ObjectBuf) {result_ptr, sizeof(uint32_t)};

        return invoke(OP_addArray, a, ObjectCounts_pack(1, 1, 0, 0));
    }

    virtual int32_t addStruct(const additionStruct &inStruct_ref, uint32_t* result_ptr) {
        ObjectArg a[2]={{{0,0}}};
        a[0].bi = (ObjectBufIn) {&inStruct_ref, sizeof(additionStruct)};
        a[1].b = (ObjectBuf) {result_ptr, sizeof(uint32_t)};

        return invoke(OP_addStruct, a, ObjectCounts_pack(1, 1, 0, 0));
    }

    virtual int32_t getStatus(statusStruct &status_ref) {
        ObjectArg a[1]={{{0,0}}};
        a[0].b = (ObjectBuf) {&status_ref, sizeof(statusStruct)};

        return invoke(OP_getStatus, a, ObjectCounts_pack(0, 1, 0, 0));
    }

};

