#pragma once

// Python 3.13 Bytecode Opcodes
// Reference: https://docs.python.org/3.13/library/dis.html

namespace justjit
{
    namespace op
    {

        // Stack manipulation
        constexpr int CACHE = 0;
        constexpr int POP_TOP = 32;
        constexpr int PUSH_NULL = 34;
        constexpr int NOP = 30;
        constexpr int COPY = 61;
        constexpr int SWAP = 115;

        // Unary operations
        constexpr int UNARY_INVERT = 41;
        constexpr int UNARY_NEGATIVE = 42;
        constexpr int UNARY_NOT = 43;
        constexpr int TO_BOOL = 40;

        // Binary operations
        constexpr int BINARY_OP = 45;
        constexpr int BINARY_SUBSCR = 5;
        constexpr int BINARY_SLICE = 4;

        // Compare operations
        constexpr int COMPARE_OP = 58;
        constexpr int CONTAINS_OP = 59;
        constexpr int IS_OP = 76;

        // Load operations
        constexpr int LOAD_CONST = 83;
        constexpr int LOAD_FAST = 85;
        constexpr int LOAD_FAST_LOAD_FAST = 88;
        constexpr int LOAD_FAST_CHECK = 87;
        constexpr int LOAD_FAST_AND_CLEAR = 86;
        constexpr int LOAD_GLOBAL = 91;
        constexpr int LOAD_NAME = 92;
        constexpr int LOAD_ATTR = 82;
        constexpr int LOAD_DEREF = 84;
        constexpr int LOAD_LOCALS = 25;
        constexpr int LOAD_FROM_DICT_OR_DEREF = 89;
        constexpr int LOAD_FROM_DICT_OR_GLOBALS = 90;

        // Store operations
        constexpr int STORE_FAST = 110;
        constexpr int STORE_FAST_LOAD_FAST = 111;
        constexpr int STORE_FAST_STORE_FAST = 112;
        constexpr int STORE_GLOBAL = 113;
        constexpr int STORE_NAME = 114;
        constexpr int STORE_ATTR = 108;
        constexpr int STORE_SUBSCR = 39;
        constexpr int STORE_SLICE = 38;
        constexpr int STORE_DEREF = 109;

        // Delete operations
        constexpr int DELETE_FAST = 65;
        constexpr int DELETE_GLOBAL = 66;
        constexpr int DELETE_NAME = 67;
        constexpr int DELETE_ATTR = 63;
        constexpr int DELETE_SUBSCR = 9;
        constexpr int DELETE_DEREF = 64;

        // Jump operations
        constexpr int JUMP_FORWARD = 79;
        constexpr int JUMP_BACKWARD = 77;
        constexpr int JUMP_BACKWARD_NO_INTERRUPT = 78;
        constexpr int POP_JUMP_IF_FALSE = 97;
        constexpr int POP_JUMP_IF_TRUE = 100;
        constexpr int POP_JUMP_IF_NONE = 98;
        constexpr int POP_JUMP_IF_NOT_NONE = 99;

        // Iteration
        constexpr int GET_ITER = 19;
        constexpr int FOR_ITER = 72;
        constexpr int END_FOR = 11;

        // Build operations
        constexpr int BUILD_LIST = 47;
        constexpr int BUILD_TUPLE = 52;
        constexpr int BUILD_MAP = 48;
        constexpr int BUILD_SET = 49;
        constexpr int BUILD_STRING = 51;
        constexpr int BUILD_SLICE = 50;
        constexpr int BUILD_CONST_KEY_MAP = 46;

        // List/Set/Dict operations
        constexpr int LIST_APPEND = 80;
        constexpr int LIST_EXTEND = 81;
        constexpr int SET_ADD = 105;
        constexpr int SET_UPDATE = 107;
        constexpr int MAP_ADD = 95;
        constexpr int DICT_MERGE = 68;
        constexpr int DICT_UPDATE = 69;

        // Unpack operations
        constexpr int UNPACK_SEQUENCE = 117;
        constexpr int UNPACK_EX = 116;

        // Call operations
        constexpr int CALL = 53;
        constexpr int CALL_KW = 57;
        constexpr int CALL_FUNCTION_EX = 54;
        constexpr int CALL_INTRINSIC_1 = 55;
        constexpr int CALL_INTRINSIC_2 = 56;

        // Return operations
        constexpr int RETURN_VALUE = 36;
        constexpr int RETURN_CONST = 103;
        constexpr int RETURN_GENERATOR = 35;

        // Function/Class
        constexpr int MAKE_FUNCTION = 26;
        constexpr int MAKE_CELL = 94;
        constexpr int COPY_FREE_VARS = 62;
        constexpr int SET_FUNCTION_ATTRIBUTE = 106;
        constexpr int LOAD_BUILD_CLASS = 24;

        // Import
        constexpr int IMPORT_NAME = 75;
        constexpr int IMPORT_FROM = 74;

        // Exception handling
        constexpr int PUSH_EXC_INFO = 33;
        constexpr int POP_EXCEPT = 31;
        constexpr int RAISE_VARARGS = 101;
        constexpr int RERAISE = 102;
        constexpr int CHECK_EXC_MATCH = 7;
        constexpr int CHECK_EG_MATCH = 6;
        constexpr int CLEANUP_THROW = 8;

        // With/Async
        constexpr int BEFORE_WITH = 2;
        constexpr int BEFORE_ASYNC_WITH = 1;
        constexpr int WITH_EXCEPT_START = 44;
        constexpr int GET_AWAITABLE = 73;
        constexpr int GET_AITER = 16;
        constexpr int GET_ANEXT = 18;
        constexpr int END_ASYNC_FOR = 10;
        constexpr int END_SEND = 12;
        constexpr int SEND = 104;
        constexpr int YIELD_VALUE = 118;
        constexpr int GET_YIELD_FROM_ITER = 21;

        // Match
        constexpr int MATCH_MAPPING = 28;
        constexpr int MATCH_SEQUENCE = 29;
        constexpr int MATCH_KEYS = 27;
        constexpr int MATCH_CLASS = 96;

        // Format
        constexpr int FORMAT_SIMPLE = 14;
        constexpr int FORMAT_WITH_SPEC = 15;
        constexpr int CONVERT_VALUE = 60;

        // Misc
        constexpr int RESUME = 149;
        constexpr int EXTENDED_ARG = 71;
        constexpr int GET_LEN = 20;
        constexpr int LOAD_ASSERTION_ERROR = 23;
        constexpr int SETUP_ANNOTATIONS = 37;
        constexpr int EXIT_INIT_CHECK = 13;
        constexpr int INTERPRETER_EXIT = 22;
        constexpr int ENTER_EXECUTOR = 70;
        constexpr int LOAD_SUPER_ATTR = 93;

        // Extended opcodes (256+)
        constexpr int JUMP = 256;
        constexpr int JUMP_NO_INTERRUPT = 257;
        constexpr int LOAD_CLOSURE = 258;
        constexpr int LOAD_METHOD = 259;
        constexpr int LOAD_SUPER_METHOD = 260;
        constexpr int LOAD_ZERO_SUPER_ATTR = 261;
        constexpr int LOAD_ZERO_SUPER_METHOD = 262;
        constexpr int POP_BLOCK = 263;
        constexpr int SETUP_CLEANUP = 264;
        constexpr int SETUP_FINALLY = 265;
        constexpr int SETUP_WITH = 266;
        constexpr int STORE_FAST_MAYBE_NULL = 267;

        // BINARY_OP argument values
        namespace binop
        {
            constexpr int ADD = 0;
            constexpr int AND = 1;
            constexpr int FLOOR_DIVIDE = 2;
            constexpr int LSHIFT = 3;
            constexpr int MATRIX_MULTIPLY = 4;
            constexpr int MULTIPLY = 5;
            constexpr int REMAINDER = 6;
            constexpr int OR = 7;
            constexpr int POWER = 8;
            constexpr int RSHIFT = 9;
            constexpr int SUBTRACT = 10;
            constexpr int TRUE_DIVIDE = 11;
            constexpr int XOR = 12;
            // Inplace variants
            constexpr int INPLACE_ADD = 13;
            constexpr int INPLACE_AND = 14;
            constexpr int INPLACE_FLOOR_DIVIDE = 15;
            constexpr int INPLACE_LSHIFT = 16;
            constexpr int INPLACE_MATRIX_MULTIPLY = 17;
            constexpr int INPLACE_MULTIPLY = 18;
            constexpr int INPLACE_REMAINDER = 19;
            constexpr int INPLACE_OR = 20;
            constexpr int INPLACE_POWER = 21;
            constexpr int INPLACE_RSHIFT = 22;
            constexpr int INPLACE_SUBTRACT = 23;
            constexpr int INPLACE_TRUE_DIVIDE = 24;
            constexpr int INPLACE_XOR = 25;
        }

        // COMPARE_OP values (extracted via arg >> 5)
        namespace cmpop
        {
            constexpr int LT = 0; // <
            constexpr int LE = 1; // <=
            constexpr int EQ = 2; // ==
            constexpr int NE = 3; // !=
            constexpr int GT = 4; // >
            constexpr int GE = 5; // >=
        }

    } // namespace op
} // namespace justjit
