/*
 * 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 GAPII_ENCODE_CONVERTERS_H
#define GAPII_ENCODE_CONVERTERS_H

#include "slice.h"

#include <gapic/coder/memory.h>
#include <gapic/scratch_allocator.h>

#include <stdio.h>
#include <string.h>

#include <string>
#include <unordered_map>

namespace gapii {

template<typename Out, typename In>
struct EncoderConverter {};


// Passthrough: T -> T
template<typename T>
struct EncoderConverter<T, T> {
    static inline T convert(const T& in, gapic::ScratchAllocator& alloc) { return in; }
};

// Passthrough: T* -> T*
template<typename T>
struct EncoderConverter<T*, T*> {
    static inline T* convert(const T* in, gapic::ScratchAllocator& alloc) { return in; }
};

// Passthrough: void* -> coder::T__P
template<typename Out>
struct EncoderConverter<Out, void*> {
    static inline Out convert(void* in, gapic::ScratchAllocator& alloc) {
        uint32_t poolID = 0; // TODO: Support non-application pools?
        uint64_t address = reinterpret_cast<uintptr_t>(in);
        return Out(address, poolID);
    }
};

// T* -> coder::T__P
template<typename Out, typename T>
struct EncoderConverter<Out, T*> {
    static inline Out convert(T* in, gapic::ScratchAllocator& alloc) {
        return EncoderConverter<Out, void*>::convert(in, alloc);
    }
};

// std::string -> const char*
template<>
struct EncoderConverter<const char*, std::string> {
    static inline const char* convert(const std::string& in, gapic::ScratchAllocator& alloc) {
        char* buf = alloc.create<char>(in.size() + 1);
        strncpy(buf, in.c_str(), in.size() + 1);
        return buf;
    }
};

// std::shared_ptr<T> -> coder::T*
template<typename T>
struct EncoderConverter<typename T::CoderType*, std::shared_ptr<T>> {
    typedef typename T::CoderType* Out;
    static inline Out convert(const std::shared_ptr<T>& in, gapic::ScratchAllocator& alloc) {
        return alloc.make<typename T::CoderType>(in->encodeable(alloc));
    }
};

// T -> coder::T
template<typename T>
struct EncoderConverter<typename T::CoderType, T> {
    static inline typename T::CoderType convert(const T& in, gapic::ScratchAllocator& alloc) {
        return in.encodeable(alloc);
    }
};

// gapii::Slice<T> -> coder::T__S
template<typename Out, typename T>
struct EncoderConverter< Out, gapii::Slice<T> > {
    static inline Out convert(const gapii::Slice<T>& in, gapic::ScratchAllocator& alloc) {
        uint32_t poolID = 0; // TODO: Support non-application pools?
        uint64_t base = reinterpret_cast<uintptr_t>(in.begin());
        uint64_t root = base; // TODO: Track root.
        return Out(gapic::coder::memory::SliceInfo(root, base, in.count(), poolID));
    }
};

// gapic::StaticArray<T, N> -> coder::T
template<typename Out, typename T, int N>
struct EncoderConverter< Out, gapic::StaticArray<T, N> > {
    static inline Out convert(const gapic::StaticArray<T, N>& in, gapic::ScratchAllocator& alloc) {
        return Out(in);
    }
};

// std::unordered_map<KeyIn, ValueIn> -> gapic::Map<KeyOut, ValueOut>
template<typename KeyOut, typename ValueOut, typename KeyIn, typename ValueIn>
struct EncoderConverter< gapic::Map<KeyOut, ValueOut>, std::unordered_map<KeyIn, ValueIn> > {
    typedef gapic::Map<KeyOut, ValueOut> Out;
    typedef std::unordered_map<KeyIn, ValueIn> In;

    static inline Out convert(const In& in, gapic::ScratchAllocator& alloc) {
        Out out = alloc.map<KeyOut, ValueOut>(in.size());
        for (auto it : in) {
            KeyOut key = EncoderConverter<KeyOut, KeyIn>::convert(it.first, alloc);
            ValueOut value = EncoderConverter<ValueOut, ValueIn>::convert(it.second, alloc);
            out.set(key, value);
        }
        return out;
    }
};

// gapic::StaticArray<ElIn, N> -> gapic::StaticArray<ElOut, N>
template<typename ElOut, typename ElIn, int N>
struct EncoderConverter< gapic::StaticArray<ElOut, N>, gapic::StaticArray<ElIn, N> > {
    static inline gapic::StaticArray<ElOut, N> convert(const gapic::StaticArray<ElIn, N>& in, gapic::ScratchAllocator& alloc) {
        gapic::StaticArray<ElOut, N> out;
        for (size_t i = 0; i < N; ++i) {
            out[i] = EncoderConverter<ElOut, ElIn>::convert(in[i], alloc);
        }
        return out;
    }
};

template <typename Out, typename In>
inline Out toEncoder(const In& in, gapic::ScratchAllocator& alloc) {
    return EncoderConverter<Out, In>::convert(in, alloc);
}

}  // namespace gapii

#endif // GAPII_ENCODE_CONVERTERS_H
