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

#ifndef ANDROID_HIDL_SUPPORT_H
#define ANDROID_HIDL_SUPPORT_H

#include <algorithm>
#include <array>
#include <iterator>
#include <cutils/native_handle.h>
#include <hidl/HidlInternal.h>
#include <hidl/Status.h>
#include <map>
#include <sstream>
#include <stddef.h>
#include <tuple>
#include <type_traits>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/StrongPointer.h>
#include <vector>

namespace android {

// this file is included by all hidl interface, so we must forward declare the
// IMemory and IBase types.
namespace hidl {
namespace memory {
namespace V1_0 {
    struct IMemory;
}; // namespace V1_0
}; // namespace manager
}; // namespace hidl

namespace hidl {
namespace base {
namespace V1_0 {
    struct IBase;
}; // namespace V1_0
}; // namespace base
}; // namespace hidl

namespace hardware {

namespace details {
// Return true on userdebug / eng builds and false on user builds.
bool debuggable();
} //  namespace details

// hidl_death_recipient is a callback interfaced that can be used with
// linkToDeath() / unlinkToDeath()
struct hidl_death_recipient : public virtual RefBase {
    virtual void serviceDied(uint64_t cookie,
            const ::android::wp<::android::hidl::base::V1_0::IBase>& who) = 0;
};

// hidl_handle wraps a pointer to a native_handle_t in a hidl_pointer,
// so that it can safely be transferred between 32-bit and 64-bit processes.
// The ownership semantics for this are:
// 1) The conversion constructor and assignment operator taking a const native_handle_t*
//    do not take ownership of the handle; this is because these operations are usually
//    just done for IPC, and cloning by default is a waste of resources. If you want
//    a hidl_handle to take ownership, call setTo(handle, true /*shouldOwn*/);
// 2) The copy constructor/assignment operator taking a hidl_handle *DO* take ownership;
//    that is because it's not intuitive that this class encapsulates a native_handle_t
//    which needs cloning to be valid; in particular, this allows constructs like this:
//    hidl_handle copy;
//    foo->someHidlCall([&](auto incoming_handle) {
//            copy = incoming_handle;
//    });
//    // copy and its enclosed file descriptors will remain valid here.
// 3) The move constructor does what you would expect; it only owns the handle if the
//    original did.
struct hidl_handle {
    hidl_handle();
    ~hidl_handle();

    hidl_handle(const native_handle_t *handle);

    // copy constructor.
    hidl_handle(const hidl_handle &other);

    // move constructor.
    hidl_handle(hidl_handle &&other);

    // assignment operators
    hidl_handle &operator=(const hidl_handle &other);

    hidl_handle &operator=(const native_handle_t *native_handle);

    hidl_handle &operator=(hidl_handle &&other);

    void setTo(native_handle_t* handle, bool shouldOwn = false);

    const native_handle_t* operator->() const;

    // implicit conversion to const native_handle_t*
    operator const native_handle_t *() const;

    // explicit conversion
    const native_handle_t *getNativeHandle() const;
private:
    void freeHandle();

    details::hidl_pointer<const native_handle_t> mHandle __attribute__ ((aligned(8)));
    bool mOwnsHandle __attribute ((aligned(8)));
};

struct hidl_string {
    hidl_string();
    ~hidl_string();

    // copy constructor.
    hidl_string(const hidl_string &);
    // copy from a C-style string. nullptr will create an empty string
    hidl_string(const char *);
    // copy the first length characters from a C-style string.
    hidl_string(const char *, size_t length);
    // copy from an std::string.
    hidl_string(const std::string &);

    // move constructor.
    hidl_string(hidl_string &&);

    const char *c_str() const;
    size_t size() const;
    bool empty() const;

    // copy assignment operator.
    hidl_string &operator=(const hidl_string &);
    // copy from a C-style string.
    hidl_string &operator=(const char *s);
    // copy from an std::string.
    hidl_string &operator=(const std::string &);
    // move assignment operator.
    hidl_string &operator=(hidl_string &&other);
    // cast to std::string.
    operator std::string() const;

    void clear();

    // Reference an external char array. Ownership is _not_ transferred.
    // Caller is responsible for ensuring that underlying memory is valid
    // for the lifetime of this hidl_string.
    void setToExternal(const char *data, size_t size);

    // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
    static const size_t kOffsetOfBuffer;

private:
    details::hidl_pointer<const char> mBuffer;
    uint32_t mSize;  // NOT including the terminating '\0'.
    bool mOwnsBuffer; // if true then mBuffer is a mutable char *

    // copy from data with size. Assume that my memory is freed
    // (through clear(), for example)
    void copyFrom(const char *data, size_t size);
    // move from another hidl_string
    void moveFrom(hidl_string &&);
};

#define HIDL_STRING_OPERATOR(OP)                                               \
    inline bool operator OP(const hidl_string &hs1, const hidl_string &hs2) {  \
        return strcmp(hs1.c_str(), hs2.c_str()) OP 0;                          \
    }                                                                          \
    inline bool operator OP(const hidl_string &hs, const char *s) {            \
        return strcmp(hs.c_str(), s) OP 0;                                     \
    }                                                                          \
    inline bool operator OP(const char *s, const hidl_string &hs) {            \
        return strcmp(hs.c_str(), s) OP 0;                                     \
    }

HIDL_STRING_OPERATOR(==)
HIDL_STRING_OPERATOR(!=)
HIDL_STRING_OPERATOR(<)
HIDL_STRING_OPERATOR(<=)
HIDL_STRING_OPERATOR(>)
HIDL_STRING_OPERATOR(>=)

#undef HIDL_STRING_OPERATOR

// Send our content to the output stream
std::ostream& operator<<(std::ostream& os, const hidl_string& str);


// hidl_memory is a structure that can be used to transfer
// pieces of shared memory between processes. The assumption
// of this object is that the memory remains accessible as
// long as the file descriptors in the enclosed mHandle
// - as well as all of its cross-process dups() - remain opened.
struct hidl_memory {

    hidl_memory() : mHandle(nullptr), mSize(0), mName("") {
    }

    /**
     * Creates a hidl_memory object, but doesn't take ownership of
     * the passed in native_handle_t; callers are responsible for
     * making sure the handle remains valid while this object is
     * used.
     */
    hidl_memory(const hidl_string &name, const native_handle_t *handle, size_t size)
      :  mHandle(handle),
         mSize(size),
         mName(name)
    {}

    // copy constructor
    hidl_memory(const hidl_memory& other) {
        *this = other;
    }

    // copy assignment
    hidl_memory &operator=(const hidl_memory &other) {
        if (this != &other) {
            mHandle = other.mHandle;
            mSize = other.mSize;
            mName = other.mName;
        }

        return *this;
    }

    // move constructor
    hidl_memory(hidl_memory&& other) {
        *this = std::move(other);
    }

    // move assignment
    hidl_memory &operator=(hidl_memory &&other) {
        if (this != &other) {
            mHandle = std::move(other.mHandle);
            mSize = other.mSize;
            mName = std::move(other.mName);
            other.mSize = 0;
        }

        return *this;
    }


    ~hidl_memory() {
    }

    const native_handle_t* handle() const {
        return mHandle;
    }

    const hidl_string &name() const {
        return mName;
    }

    uint64_t size() const {
        return mSize;
    }

    // offsetof(hidl_memory, mHandle) exposed since mHandle is private.
    static const size_t kOffsetOfHandle;
    // offsetof(hidl_memory, mName) exposed since mHandle is private.
    static const size_t kOffsetOfName;

private:
    hidl_handle mHandle __attribute__ ((aligned(8)));
    uint64_t mSize __attribute__ ((aligned(8)));
    hidl_string mName __attribute__ ((aligned(8)));
};

////////////////////////////////////////////////////////////////////////////////

template<typename T>
struct hidl_vec {
    hidl_vec()
        : mBuffer(NULL),
          mSize(0),
          mOwnsBuffer(true) {
        static_assert(hidl_vec<T>::kOffsetOfBuffer == 0, "wrong offset");
    }

    hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
        *this = other;
    }

    hidl_vec(hidl_vec<T> &&other)
    : mOwnsBuffer(false) {
        *this = std::move(other);
    }

    hidl_vec(const std::initializer_list<T> list)
            : mOwnsBuffer(true) {
        if (list.size() > UINT32_MAX) {
            details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
        }
        mSize = static_cast<uint32_t>(list.size());
        mBuffer = new T[mSize];

        size_t idx = 0;
        for (auto it = list.begin(); it != list.end(); ++it) {
            mBuffer[idx++] = *it;
        }
    }

    hidl_vec(const std::vector<T> &other) : hidl_vec() {
        *this = other;
    }

    template <typename InputIterator,
              typename = typename std::enable_if<std::is_convertible<
                  typename std::iterator_traits<InputIterator>::iterator_category,
                  std::input_iterator_tag>::value>::type>
    hidl_vec(InputIterator first, InputIterator last) : mOwnsBuffer(true) {
        auto size = std::distance(first, last);
        if (size > static_cast<int64_t>(UINT32_MAX)) {
            details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
        }
        if (size < 0) {
            details::logAlwaysFatal("size can't be negative.");
        }
        mSize = static_cast<uint32_t>(size);
        mBuffer = new T[mSize];

        size_t idx = 0;
        for (; first != last; ++first) {
            mBuffer[idx++] = static_cast<T>(*first);
        }
    }

    ~hidl_vec() {
        if (mOwnsBuffer) {
            delete[] mBuffer;
        }
        mBuffer = NULL;
    }

    // Reference an existing array, optionally taking ownership. It is the
    // caller's responsibility to ensure that the underlying memory stays
    // valid for the lifetime of this hidl_vec.
    void setToExternal(T *data, size_t size, bool shouldOwn = false) {
        if (mOwnsBuffer) {
            delete [] mBuffer;
        }
        mBuffer = data;
        if (size > UINT32_MAX) {
            details::logAlwaysFatal("external vector size exceeds 2^32 elements.");
        }
        mSize = static_cast<uint32_t>(size);
        mOwnsBuffer = shouldOwn;
    }

    T *data() {
        return mBuffer;
    }

    const T *data() const {
        return mBuffer;
    }

    T *releaseData() {
        if (!mOwnsBuffer && mSize > 0) {
            resize(mSize);
        }
        mOwnsBuffer = false;
        return mBuffer;
    }

    hidl_vec &operator=(hidl_vec &&other) {
        if (mOwnsBuffer) {
            delete[] mBuffer;
        }
        mBuffer = other.mBuffer;
        mSize = other.mSize;
        mOwnsBuffer = other.mOwnsBuffer;
        other.mOwnsBuffer = false;
        return *this;
    }

    hidl_vec &operator=(const hidl_vec &other) {
        if (this != &other) {
            if (mOwnsBuffer) {
                delete[] mBuffer;
            }
            copyFrom(other, other.mSize);
        }

        return *this;
    }

    // copy from an std::vector.
    hidl_vec &operator=(const std::vector<T> &other) {
        if (mOwnsBuffer) {
            delete[] mBuffer;
        }
        copyFrom(other, other.size());
        return *this;
    }

    // cast to an std::vector.
    operator std::vector<T>() const {
        std::vector<T> v(mSize);
        for (size_t i = 0; i < mSize; ++i) {
            v[i] = mBuffer[i];
        }
        return v;
    }

    // equality check, assuming that T::operator== is defined.
    bool operator==(const hidl_vec &other) const {
        if (mSize != other.size()) {
            return false;
        }
        for (size_t i = 0; i < mSize; ++i) {
            if (!(mBuffer[i] == other.mBuffer[i])) {
                return false;
            }
        }
        return true;
    }

    // inequality check, assuming that T::operator== is defined.
    inline bool operator!=(const hidl_vec &other) const {
        return !((*this) == other);
    }

    size_t size() const {
        return mSize;
    }

    T &operator[](size_t index) {
        return mBuffer[index];
    }

    const T &operator[](size_t index) const {
        return mBuffer[index];
    }

    void resize(size_t size) {
        if (size > UINT32_MAX) {
            details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
        }
        T *newBuffer = new T[size];

        for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) {
            newBuffer[i] = mBuffer[i];
        }

        if (mOwnsBuffer) {
            delete[] mBuffer;
        }
        mBuffer = newBuffer;

        mSize = static_cast<uint32_t>(size);
        mOwnsBuffer = true;
    }

    // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
    static const size_t kOffsetOfBuffer;

private:
    // Define std interator interface for walking the array contents
    template<bool is_const>
    class iter : public std::iterator<
            std::random_access_iterator_tag, /* Category */
            T,
            ptrdiff_t, /* Distance */
            typename std::conditional<is_const, const T *, T *>::type /* Pointer */,
            typename std::conditional<is_const, const T &, T &>::type /* Reference */>
    {
        using traits = std::iterator_traits<iter>;
        using ptr_type = typename traits::pointer;
        using ref_type = typename traits::reference;
        using diff_type = typename traits::difference_type;
    public:
        iter(ptr_type ptr) : mPtr(ptr) { }
        inline iter &operator++()    { mPtr++; return *this; }
        inline iter  operator++(int) { iter i = *this; mPtr++; return i; }
        inline iter &operator--()    { mPtr--; return *this; }
        inline iter  operator--(int) { iter i = *this; mPtr--; return i; }
        inline friend iter operator+(diff_type n, const iter &it) { return it.mPtr + n; }
        inline iter  operator+(diff_type n) const { return mPtr + n; }
        inline iter  operator-(diff_type n) const { return mPtr - n; }
        inline diff_type operator-(const iter &other) const { return mPtr - other.mPtr; }
        inline iter &operator+=(diff_type n) { mPtr += n; return *this; }
        inline iter &operator-=(diff_type n) { mPtr -= n; return *this; }
        inline ref_type operator*() const  { return *mPtr; }
        inline ptr_type operator->() const { return mPtr; }
        inline bool operator==(const iter &rhs) const { return mPtr == rhs.mPtr; }
        inline bool operator!=(const iter &rhs) const { return mPtr != rhs.mPtr; }
        inline bool operator< (const iter &rhs) const { return mPtr <  rhs.mPtr; }
        inline bool operator> (const iter &rhs) const { return mPtr >  rhs.mPtr; }
        inline bool operator<=(const iter &rhs) const { return mPtr <= rhs.mPtr; }
        inline bool operator>=(const iter &rhs) const { return mPtr >= rhs.mPtr; }
        inline ref_type operator[](size_t n) const { return mPtr[n]; }
    private:
        ptr_type mPtr;
    };
public:
    using iterator       = iter<false /* is_const */>;
    using const_iterator = iter<true  /* is_const */>;

    iterator begin() { return data(); }
    iterator end() { return data()+mSize; }
    const_iterator begin() const { return data(); }
    const_iterator end() const { return data()+mSize; }

private:
    details::hidl_pointer<T> mBuffer;
    uint32_t mSize;
    bool mOwnsBuffer;

    // copy from an array-like object, assuming my resources are freed.
    template <typename Array>
    void copyFrom(const Array &data, size_t size) {
        mSize = static_cast<uint32_t>(size);
        mOwnsBuffer = true;
        if (mSize > 0) {
            mBuffer = new T[size];
            for (size_t i = 0; i < size; ++i) {
                mBuffer[i] = data[i];
            }
        } else {
            mBuffer = NULL;
        }
    }
};

template <typename T>
const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);

////////////////////////////////////////////////////////////////////////////////

namespace details {

    template<size_t SIZE1, size_t... SIZES>
    struct product {
        static constexpr size_t value = SIZE1 * product<SIZES...>::value;
    };

    template<size_t SIZE1>
    struct product<SIZE1> {
        static constexpr size_t value = SIZE1;
    };

    template<typename T, size_t SIZE1, size_t... SIZES>
    struct std_array {
        using type = std::array<typename std_array<T, SIZES...>::type, SIZE1>;
    };

    template<typename T, size_t SIZE1>
    struct std_array<T, SIZE1> {
        using type = std::array<T, SIZE1>;
    };

    template<typename T, size_t SIZE1, size_t... SIZES>
    struct accessor {

        using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;

        explicit accessor(T *base)
            : mBase(base) {
        }

        accessor<T, SIZES...> operator[](size_t index) {
            return accessor<T, SIZES...>(
                    &mBase[index * product<SIZES...>::value]);
        }

        accessor &operator=(const std_array_type &other) {
            for (size_t i = 0; i < SIZE1; ++i) {
                (*this)[i] = other[i];
            }
            return *this;
        }

    private:
        T *mBase;
    };

    template<typename T, size_t SIZE1>
    struct accessor<T, SIZE1> {

        using std_array_type = typename std_array<T, SIZE1>::type;

        explicit accessor(T *base)
            : mBase(base) {
        }

        T &operator[](size_t index) {
            return mBase[index];
        }

        accessor &operator=(const std_array_type &other) {
            for (size_t i = 0; i < SIZE1; ++i) {
                (*this)[i] = other[i];
            }
            return *this;
        }

    private:
        T *mBase;
    };

    template<typename T, size_t SIZE1, size_t... SIZES>
    struct const_accessor {

        using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;

        explicit const_accessor(const T *base)
            : mBase(base) {
        }

        const_accessor<T, SIZES...> operator[](size_t index) const {
            return const_accessor<T, SIZES...>(
                    &mBase[index * product<SIZES...>::value]);
        }

        operator std_array_type() {
            std_array_type array;
            for (size_t i = 0; i < SIZE1; ++i) {
                array[i] = (*this)[i];
            }
            return array;
        }

    private:
        const T *mBase;
    };

    template<typename T, size_t SIZE1>
    struct const_accessor<T, SIZE1> {

        using std_array_type = typename std_array<T, SIZE1>::type;

        explicit const_accessor(const T *base)
            : mBase(base) {
        }

        const T &operator[](size_t index) const {
            return mBase[index];
        }

        operator std_array_type() {
            std_array_type array;
            for (size_t i = 0; i < SIZE1; ++i) {
                array[i] = (*this)[i];
            }
            return array;
        }

    private:
        const T *mBase;
    };

}  // namespace details

////////////////////////////////////////////////////////////////////////////////

// A multidimensional array of T's. Assumes that T::operator=(const T &) is defined.
template<typename T, size_t SIZE1, size_t... SIZES>
struct hidl_array {

    using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type;

    hidl_array() = default;

    // Copies the data from source, using T::operator=(const T &).
    hidl_array(const T *source) {
        for (size_t i = 0; i < elementCount(); ++i) {
            mBuffer[i] = source[i];
        }
    }

    // Copies the data from the given std::array, using T::operator=(const T &).
    hidl_array(const std_array_type &array) {
        details::accessor<T, SIZE1, SIZES...> modifier(mBuffer);
        modifier = array;
    }

    T *data() { return mBuffer; }
    const T *data() const { return mBuffer; }

    details::accessor<T, SIZES...> operator[](size_t index) {
        return details::accessor<T, SIZES...>(
                &mBuffer[index * details::product<SIZES...>::value]);
    }

    details::const_accessor<T, SIZES...> operator[](size_t index) const {
        return details::const_accessor<T, SIZES...>(
                &mBuffer[index * details::product<SIZES...>::value]);
    }

    // equality check, assuming that T::operator== is defined.
    bool operator==(const hidl_array &other) const {
        for (size_t i = 0; i < elementCount(); ++i) {
            if (!(mBuffer[i] == other.mBuffer[i])) {
                return false;
            }
        }
        return true;
    }

    inline bool operator!=(const hidl_array &other) const {
        return !((*this) == other);
    }

    using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;

    static constexpr size_tuple_type size() {
        return std::make_tuple(SIZE1, SIZES...);
    }

    static constexpr size_t elementCount() {
        return details::product<SIZE1, SIZES...>::value;
    }

    operator std_array_type() const {
        return details::const_accessor<T, SIZE1, SIZES...>(mBuffer);
    }

private:
    T mBuffer[elementCount()];
};

// An array of T's. Assumes that T::operator=(const T &) is defined.
template<typename T, size_t SIZE1>
struct hidl_array<T, SIZE1> {

    using std_array_type = typename details::std_array<T, SIZE1>::type;

    hidl_array() = default;

    // Copies the data from source, using T::operator=(const T &).
    hidl_array(const T *source) {
        for (size_t i = 0; i < elementCount(); ++i) {
            mBuffer[i] = source[i];
        }
    }

    // Copies the data from the given std::array, using T::operator=(const T &).
    hidl_array(const std_array_type &array) : hidl_array(array.data()) {}

    T *data() { return mBuffer; }
    const T *data() const { return mBuffer; }

    T &operator[](size_t index) {
        return mBuffer[index];
    }

    const T &operator[](size_t index) const {
        return mBuffer[index];
    }

    // equality check, assuming that T::operator== is defined.
    bool operator==(const hidl_array &other) const {
        for (size_t i = 0; i < elementCount(); ++i) {
            if (!(mBuffer[i] == other.mBuffer[i])) {
                return false;
            }
        }
        return true;
    }

    inline bool operator!=(const hidl_array &other) const {
        return !((*this) == other);
    }

    static constexpr size_t size() { return SIZE1; }
    static constexpr size_t elementCount() { return SIZE1; }

    // Copies the data to an std::array, using T::operator=(T).
    operator std_array_type() const {
        std_array_type array;
        for (size_t i = 0; i < SIZE1; ++i) {
            array[i] = mBuffer[i];
        }
        return array;
    }

private:
    T mBuffer[SIZE1];
};

// ----------------------------------------------------------------------
// Version functions
struct hidl_version {
public:
    constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}

    bool operator==(const hidl_version& other) const {
        return (mMajor == other.get_major() && mMinor == other.get_minor());
    }

    bool operator<(const hidl_version& other) const {
        return (mMajor < other.get_major() ||
                (mMajor == other.get_major() && mMinor < other.get_minor()));
    }

    bool operator>(const hidl_version& other) const {
        return other < *this;
    }

    bool operator<=(const hidl_version& other) const {
        return !(*this > other);
    }

    bool operator>=(const hidl_version& other) const {
        return !(*this < other);
    }

    constexpr uint16_t get_major() const { return mMajor; }
    constexpr uint16_t get_minor() const { return mMinor; }

private:
    uint16_t mMajor;
    uint16_t mMinor;
};

inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
    return hidl_version(major,minor);
}

///////////////////// toString functions

std::string toString(const void *t);

// toString alias for numeric types
template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
inline std::string toString(T t) {
    return std::to_string(t);
}

namespace details {

template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
inline std::string toHexString(T t, bool prefix = true) {
    std::ostringstream os;
    if (prefix) { os << std::showbase; }
    os << std::hex << t;
    return os.str();
}

template<>
inline std::string toHexString(uint8_t t, bool prefix) {
    return toHexString(static_cast<int32_t>(t), prefix);
}

template<>
inline std::string toHexString(int8_t t, bool prefix) {
    return toHexString(static_cast<int32_t>(t), prefix);
}

template<typename Array>
std::string arrayToString(const Array &a, size_t size);

template<size_t SIZE1>
std::string arraySizeToString() {
    return std::string{"["} + toString(SIZE1) + "]";
}

template<size_t SIZE1, size_t SIZE2, size_t... SIZES>
std::string arraySizeToString() {
    return std::string{"["} + toString(SIZE1) + "]" + arraySizeToString<SIZE2, SIZES...>();
}

template<typename T, size_t SIZE1>
std::string toString(details::const_accessor<T, SIZE1> a) {
    return arrayToString(a, SIZE1);
}

template<typename Array>
std::string arrayToString(const Array &a, size_t size) {
    using android::hardware::toString;
    std::string os;
    os += "{";
    for (size_t i = 0; i < size; ++i) {
        if (i > 0) {
            os += ", ";
        }
        os += toString(a[i]);
    }
    os += "}";
    return os;
}

template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
std::string toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...> a) {
    return arrayToString(a, SIZE1);
}

}  //namespace details

inline std::string toString(const void *t) {
    return details::toHexString(reinterpret_cast<uintptr_t>(t));
}

// debug string dump. There will be quotes around the string!
inline std::string toString(const hidl_string &hs) {
    return std::string{"\""} + hs.c_str() + "\"";
}

// debug string dump
inline std::string toString(const hidl_handle &hs) {
    return toString(hs.getNativeHandle());
}

inline std::string toString(const hidl_memory &mem) {
    return std::string{"memory {.name = "} + toString(mem.name()) + ", .size = "
              + toString(mem.size())
              + ", .handle = " + toString(mem.handle()) + "}";
}

inline std::string toString(const sp<hidl_death_recipient> &dr) {
    return std::string{"death_recipient@"} + toString(dr.get());
}

// debug string dump, assuming that toString(T) is defined.
template<typename T>
std::string toString(const hidl_vec<T> &a) {
    std::string os;
    os += "[" + toString(a.size()) + "]";
    os += details::arrayToString(a, a.size());
    return os;
}

template<typename T, size_t SIZE1>
std::string toString(const hidl_array<T, SIZE1> &a) {
    return details::arraySizeToString<SIZE1>()
            + details::toString(details::const_accessor<T, SIZE1>(a.data()));
}

template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
std::string toString(const hidl_array<T, SIZE1, SIZE2, SIZES...> &a) {
    return details::arraySizeToString<SIZE1, SIZE2, SIZES...>()
            + details::toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...>(a.data()));
}

}  // namespace hardware
}  // namespace android


#endif  // ANDROID_HIDL_SUPPORT_H
