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

#include "base_type.h"
#include "memory_manager.h"

#include <gapic/log.h>
#include <gapic/static_array.h>

#include <stdint.h>
#include <string.h>

#include <vector>

namespace gapir {

// Strongly typed, limited size stack for the stack based virtual machine. If an invalid operation
// is called on the stack then the stack will go into an invalid state where each operation is no op
// (except print stack). From an invalid state the stack can't go back to a valid state again.
class Stack {
public:
    // Representation of an unconverted value from the stack.
    typedef uint64_t BaseValue;

    // Construct a new stack with the given size and memory manager
    // The memory manager is needed to resolve constant and volatile pointers to absolute pointers
    Stack(uint32_t size, const MemoryManager* memoryManager);

    // Pop the element from the top of the stack as the given type if its type is matching with the
    // given type. For pointer types convert the pointer to an absolute pointer before returning it.
    // Puts the stack into an invalid state if called on an empty stack or if the requested type
    // doesn't match with the type of the value at the top of the stack.
    template <typename T>
    T pop() {
        if (!popCheck("pop")) {
            return T();
        }
        GAPID_DEBUG("-%s pop()", mStack[mTop-1].debugInfo(mMemoryManager));
        return PopImpl<T>::pop(this);
    }

    // Pop the static array (stored as a pointer) from the top of the stack.
    template <typename T, int N>
    gapic::StaticArray<T, N> pop() {
        T* ptr = pop<T*>();
        gapic::StaticArray<T, N> out;
        for (int i = 0; i < N; i++) {
          out[i] = ptr[i];
        }
        return out;
    }

    // Pop the volatile pointer from the top of the stack. If the top element
    // is not a volatile pointer puts the stack into and invalid state. Also,
    // puts the stack into an invalid state if called on an empty stack.
    // Use with care, this template casts a pointer to a T* with no way of
    // knowing if that is safe.
    template <typename T>
    T* popVolatile() {
        if (!popCheck("popVolatile")) {
            return nullptr;
        }
        BaseType type = getTopType();
        if (type != BaseType::VolatilePointer) {
            GAPID_WARNING("popVolatile called for type %s", baseTypeName(type));
            mValid = false;
            return nullptr;
        }
        return pop<T*>();
    }

    // Pop the constant pointer from the top of the stack. If the top element
    // is not a constant pointer puts the stack into and invalid state. Also,
    // puts the stack into an invalid state if called on an empty stack.
    // Use with care, this template casts a pointer to a const T* with no way of
    // knowing if that is safe.
    template <typename T>
    const T* popConstant() {
        if (!popCheck("popConstant")) {
            return nullptr;
        }
        BaseType type = getTopType();
        if (type != BaseType::ConstantPointer) {
            GAPID_WARNING("popConstant called for type %s", baseTypeName(type));
            mValid = false;
            return nullptr;
        }
        return pop<const T*>();
    }

    // Pop the element from the top of the stack and return its unconverted typed value.
    // Puts the stack into an invalid state if called on an empty stack.
    BaseValue popBaseValue() {
        if (!popCheck("popBaseValue")) {
            return 0;
        }
        mTop--;
        return mStack[mTop].getBaseValue();
    }

    // Push the given type and base value to the top of the stack. Put the
    // stack into invalid state if called on a full stack.
    void pushValue(BaseType type, BaseValue value) {
        if (!pushCheck("pushValue")) {
            return;
        }
        pushFrom(type, &value);
        checkTopForInvalidPointer("pushValue");
    }

    // Push the given value to the top of the stack with a type determined by the type of the value
    // given. Put the stack into invalid state if called on a full stack.
    template <typename T>
    void push(T value) {
        if (!pushCheck("push")) {
            return;
        }

        mStack[mTop].set(value);
        if (!checkTopForInvalidPointer("push")) {
            return;
        }
        GAPID_DEBUG("+%s push()", mStack[mTop].debugInfo(mMemoryManager));
        mTop++;
    }

    // Returns the type of the element at the top of the stack. Put the stack into invalid state if
    // called on an empty stack.
    BaseType getTopType();

    // Discards count amount of elements from the top of the stack. Put the stack into invalid state
    // if the stack contains fewer element then the given count.
    void discard(uint32_t count);

    // Clone the n-th element from the top of the stack to the top of the stack. The currently top
    // most element is the 0th and the index is increasing with going down in the stack. Put the
    // stack into invalid state if called on a full stacked or if the given index points out from
    // the stack (greater then current size minus one).
    void clone(uint32_t n);

    // Print the content of the stack to the log output. The output is only written to the log
    // output if the debug level is at least DEBUG. This function will work even if the stack is not
    // in a valid state.
    void printStack() const;

    // Returns if the stack is in a valid state or not.
    bool isValid() const {
        return mValid;
    }

    // Pop the item from the top of the stack to the given memory address. The number of bytes
    // written to the address is determined by the type of the element at the top of the stack.
    // Pointers are converted to absolute pointers before writing to the address.
    // The stack will enter an invalid state if called on an empty stack.
    // Take care if using an address on the program stack. Use getTopType()
    // to check the type of the object you will pop and/or
    // make sure the receiver is sizeof(BaseValue).
    void popTo(void* address);

    // Push a new item to the stack with the given type from the given memory address. Put the stack
    // into invalid state if it is already full before the call.
    void pushFrom(BaseType type, const void* data);
private:
    // Check that the stack is valid and a pop is allowed (non-empty).
    bool popCheck(const char * what);
    // Check that the stack is valid and a push is allowed (non-full).
    bool pushCheck(const char * what);
    // Check that if top is a pointer type that it is valid.
    bool checkTopForInvalidPointer(const char *what);
    // Check that top is a pointer type, that it is valid and return it.
    const void* checkAndGetTopPointer(const char *what);

    // Implementation of the pop method for non pointer types.
    template <typename T>
    struct PopImpl {
        static T pop(Stack* stack) {
            stack->mTop--;
            BaseType baseType = TypeToBaseType<typename std::remove_cv<T>::type>::type;
            if (stack->mStack[stack->mTop].type() != baseType) {
                stack->mValid = false;
                GAPID_WARNING(
                        "Pop type (%s) doesn't match with the type at the top of the stack (%s)",
                        baseTypeName(baseType),
                        baseTypeName(stack->mStack[stack->mTop].type()));
                return T();
            }
            return stack->mStack[stack->mTop].value<T>();
        }
    };

    // Implementation of the pop method for pointer types.
    // Use with care, this template casts a pointer to a T* with no
    // way of knowing if that is safe.
    template <typename T>
    struct PopImpl<T*> {
        static T* pop(Stack* stack) {
            stack->mTop--;
            const void* pointer = stack->checkAndGetTopPointer("pop");
            return const_cast<T*>(static_cast<const T*>(pointer));
        }
    };

    class Entry {
    public:
        const void* valuePtr() const {
            return &mValue;
        }

        template <typename T>
        const T value() const {
            static_assert(sizeof(mValue) >= sizeof(T),
                          "T is too large to be used as value");
            T t;
            if (!getTo(&t)) {
                GAPID_WARNING(
                    "Error: read stack value inappropriate type %s wanted %s",
                    baseTypeName(mType), baseTypeName(TypeToBaseType<T>::type));
                return T();
            }
            return t;
        }

        const BaseType& type() const {
            return mType;
        }

        void set(bool b) {
            mType = TypeToBaseType<bool>::type;
            mValue.b = b;
        }
        void set(int8_t i8) {
            mType = TypeToBaseType<int8_t>::type;
            mValue.i8 = i8;
        }
        void set(int16_t i16) {
            mType = TypeToBaseType<int16_t>::type;
            mValue.i16 = i16;
        }
        void set(int32_t i32) {
            mType = TypeToBaseType<int32_t>::type;
            mValue.i32 = i32;
        }
        void set(int64_t i64) {
            mType = TypeToBaseType<int64_t>::type;
            mValue.i64 = i64;
        }
        void set(uint8_t u8) {
            mType = TypeToBaseType<uint8_t>::type;
            mValue.u8 = u8;
        }
        void set(uint16_t u16) {
            mType = TypeToBaseType<uint16_t>::type;
            mValue.u16 = u16;
        }
        void set(uint32_t u32) {
            mType = TypeToBaseType<uint32_t>::type;
            mValue.u32 = u32;
        }
        void set(uint64_t u64) {
            mType = TypeToBaseType<uint64_t>::type;
            mValue.u64 = u64;
        }
        void set(float f) {
            mType = TypeToBaseType<float>::type;
            mValue.f = f;
        }
        void set(double d) {
            mType = TypeToBaseType<double>::type;
            mValue.d = d;
        }

        template <typename T>
        void set(T* p) {
            mType = BaseType::AbsolutePointer;
            mValue.p = p;
        }

        template <typename T>
        void set(T val) {
            static_assert(sizeof(T) == sizeof(mValue.u32),
                          "Enum base type is not uint32_t");
            mType = BaseType::Uint32;
            mValue.u32 = uint32_t(val);
        }

        void set(BaseType type, const void* data) {
            // Little endian assumption
            memcpy(&mValue, data, baseTypeSize(type));
            mType = type;
        }

        bool getTo(bool* b) const {
            if (mType != TypeToBaseType<bool>::type) {
                return false;
            }
            *b = mValue.b;
            return true;
        }
        bool getTo(int8_t* i8) const {
            if (mType != TypeToBaseType<int8_t>::type) {
                return false;
            }
            *i8 = mValue.i8;
            return true;
        }
        bool getTo(int16_t* i16) const {
            if (mType != TypeToBaseType<int16_t>::type) {
                return false;
            }
            *i16 = mValue.i16;
            return true;
        }
        bool getTo(int32_t* i32) const {
            if (mType != TypeToBaseType<int32_t>::type) {
                return false;
            }
            *i32 = mValue.i32;
            return true;
        }
        bool getTo(int64_t* i64) const {
            if (mType != TypeToBaseType<int64_t>::type) {
                return false;
            }
            *i64 = mValue.i64;
            return true;
        }
        bool getTo(uint8_t* u8) const {
            if (mType != TypeToBaseType<uint8_t>::type) {
                return false;
            }
            *u8 = mValue.u8;
            return true;
        }
        bool getTo(uint16_t* u16) const {
            if (mType != TypeToBaseType<uint16_t>::type) {
                return false;
            }
            *u16 = mValue.u16;
            return true;
        }
        bool getTo(uint32_t* u32) const {
            if (mType != TypeToBaseType<uint32_t>::type &&
                mType != BaseType::VolatilePointer &&
                mType != BaseType::ConstantPointer) {
                return false;
            }
            *u32 = mValue.u32;
            return true;
        }
        bool getTo(uint64_t* u64) const {
            if (mType != TypeToBaseType<uint64_t>::type) {
                return false;
            }
            *u64 = mValue.u64;
            return true;
        }
        bool getTo(float* f) const {
            if (mType != TypeToBaseType<float>::type) {
                return false;
            }
            *f = mValue.f;
            return true;
        }
        bool getTo(double* d) const {
            if (mType != TypeToBaseType<double>::type) {
                return false;
            }
            *d = mValue.d;
            return true;
        }

        template <typename T>
        bool getTo(T* val) const {
            static_assert(sizeof(T) == sizeof(mValue.u32),
                          "Enum base type is not uint32_t");
            if (mType != BaseType::Uint32) {
                return false;
            }
            *val = T(mValue.u32);
            return true;
        }

        bool getTo(const void** p) const {
            if (mType != BaseType::AbsolutePointer) {
                return false;
            }
            *p = mValue.p;
            return true;
        }

        bool getTo(void** p) const {
            if (mType != BaseType::AbsolutePointer) {
                return false;
            }
            *p = mValue.p;
            return true;
        }

        BaseValue getBaseValue() const {
            return mValue.bv;
        }

        // Return a string describing the stack entry.
        // The pointer returned is only valid until the next call to debugInfo, regardless of the
        // Entry instance.
        // This function is not thread safe.
        const char* debugInfo(const MemoryManager* memoryManager) const;
    private:
        // Type of the element stored by this entry
        BaseType mType;

        // Union of all possible types stored on the stack for creating a unified value type with
        // getter function to access the value as a specific type
        union ValueType {
            bool     b;
            int8_t   i8;
            int16_t  i16;
            int32_t  i32;
            int64_t  i64;
            uint8_t  u8;
            uint16_t u16;
            uint32_t u32;
            uint64_t u64;
            float    f;
            double   d;
            void*    p;
            BaseValue bv;
        };

        ValueType mValue;

        static_assert(sizeof(BaseValue) >= sizeof(ValueType),
                      "Stack::BaseValue is not large enough");
    };

    // Indicates if the stack is in a consistent state (true value) or not (false value). The stack
    // go into an inconsistent state after an invalid operation. When mValid is false then all of
    // the operation on the stack (expect printing the stack) produce a warning message and falls
    // back to no op (with zero initialized return value where necessary). The stack can't go back
    // from an invalid state to a valid state again.
    bool mValid;

    // Contains the offset of the first empty slot in the stack from the bottom of the stack. The
    // value of it indicates the number of elements currently in the stack.
    uint32_t mTop;

    // mStack stores the entries currently in the stack. The 0th element corresponds to the bottom
    // of the stack.
    std::vector<Entry> mStack;

    // Reference to the memory manager used to resolve constant and volatile pointers to absolute
    // pointers when thy are popped from the stack.
    const MemoryManager* mMemoryManager;
};

}  // namespace gapir

#endif  // GAPIR_STACK_H
