#pragma once

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

namespace spider {

    /**
     * Implements an instruction reel.
     */
    class InstrReel {
    protected: // Current accessing range //

        u8* _mem;
        isize _size;
        isize _offset;
        isize _total_size;

    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 atU8(u64 ip);

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

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

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

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

    public: // Static Utils //

        static u16 unpackInstr(u16 bcode);

        static u8 unpackAddrMode(u16 bcode);

        static u8 unpackTypeSize(u16 bcode);

    };

}
