#pragma once

#include <spider/SpiderRuntime.hpp>
#include <spider/runtime/memory/ByteArray.hpp>

namespace spider {

    /**
     * Implements an instruction reel.
     */
    class InstrReel {
    public:

        InstrReel();

        virtual ~InstrReel();

    public:

        /**
         * Obtains a byte of data at
         * the specific location.
         * Reindexing may occur, continous access
         * may incurr in less penalties.
         */
        virtual u8 readU8(u64 ip) = 0;

        /**
         * Obtains a byte of data at
         * the specific location.
         * Reindexing may occur, continous access
         * may incurr in less penalties.
         */
        virtual u16 readU16(u64 ip) = 0;

        /**
         * Obtains a byte of data at
         * the specific location.
         * Reindexing may occur, continous access
         * may incurr in less penalties.
         */
        virtual u32 readU32(u64 ip) = 0;

        /**
         * Obtains a byte of data at
         * the specific location.
         * Reindexing may occur, continous access
         * may incurr in less penalties.
         */
        virtual u64 readU64(u64 ip) = 0;

        /**
         * Reads a range of data, and
         * outputs it.
         */
        virtual void readRange(u64 ip, u8* out, u64 length) = 0;

        /**
         * Current size of the instructions.
         */
        virtual u64 size() = 0;

    public: // Static Utils //

        static u16 unpackInstr(u16 bcode);

        static u8 unpackAddrMode(u16 bcode);

        static u8 unpackTypeSize(u16 bcode);

    };

}
