from typing import List, Iterator
from angrmanagement.ui.widgets.qblock import QBlock
from PySide2.QtGui import QColor, QPainter
from angrmanagement.plugins import BasePlugin
import logging
from ..data.jobs.loading import LoadBinaryJob
from PySide2.QtWidgets import QApplication, QFileDialog


_l = logging.getLogger(__name__)


class CustomVmArch(BasePlugin):
    def __init__(self, workspace):
        super().__init__(workspace)

        self.workspace.instance.register_container('custom_vm_arch', lambda: [], List[int],
                                              'Supported Custom VMs and Architectures')
        self.custom_vm_arch.am_subscribe(self.brainfuck)

    MENU_BUTTONS = ('Brainfuck', 'Berkeley Packet Filter', 'Cybertronix64k', 'Atmel AVR', 'Add new VM/Arch')

    @property
    def custom_vm_arch(self):
        return self.workspace.instance.custom_vm_arch

    BRAINFUCK_ID = 0
    BPF_ID = 1
    CYBERTRONIX_ID = 2
    AVR_ID = 3
    NEW_ARCH_ID = 4

    def handle_click_menu(self, idx):
        _l.warning("handle_click")

        if idx < 0 or idx >= len(self.MENU_BUTTONS):
            return

        mapping = {
            self.BRAINFUCK_ID: self.brainfuck,
            self.BPF_ID: self.bpf,
            self.CYBERTRONIX_ID: self.cybertronix,
            self.AVR_ID: self.avr,
            self.NEW_ARCH_ID: self.new_vm_arch,
        }

        mapping.get(idx)()

    # GRAPH_TRACE_LEGEND_WIDTH = 30
    # GRAPH_TRACE_LEGEND_SPACING = 20
    #
    # def draw_block(self, qblock: QBlock, painter: QPainter):
    #     _l.warning("draw_block")
    #     w = 5
    #     h = 5
    #     legend_x = 0 - self.GRAPH_TRACE_LEGEND_WIDTH - self.GRAPH_TRACE_LEGEND_SPACING
    #     painter.drawRect(legend_x, 0, w, h)

    def brainfuck(self):
        _l.warning("brainfuck")
        # view = self.workspace.view_manager.first_view_in_category('disassembly')
        # view.redraw_current_graph()
        # self.workspace.instance.add_job(LoadBinaryJob(file_path))

    def bpf(self):
        _l.warning("Berkeley Packet Filter (BPF)")

    def cybertronix(self):
        _l.warning("CyberTronix64k")

    def avr(self):
        _l.warning("Atmel AVR")

    def new_vm_arch(self):
        _l.warning("new_vm_arch")
        tfilter = 'json (*.json)'
        file_path, _ = QFileDialog.getOpenFileName(None, "Open the json file with arch info", "", tfilter)
        try:
            with open(file_path, 'rb') as f:
                f.read(1)
        except FileNotFoundError:
            return None




from typing import List, Iterator
from angrmanagement.ui.widgets.qblock import QBlock
from PySide2.QtGui import QColor, QPainter
from angrmanagement.plugins import BasePlugin
import logging
from ..data.jobs.loading import LoadBinaryJob
from PySide2.QtWidgets import QApplication, QFileDialog


_l = logging.getLogger(__name__)


class CustomVmArch(BasePlugin):
    def __init__(self, workspace):
        super().__init__(workspace)

        self.workspace.instance.register_container('custom_vm_arch', lambda: [], List[int],
                                              'Supported Custom VMs and Architectures')
        self.custom_vm_arch.am_subscribe(self.brainfuck)

    MENU_BUTTONS = ('Brainfuck', 'Berkeley Packet Filter', 'Cybertronix64k', 'Atmel AVR', 'Add new VM/Arch')

    @property
    def custom_vm_arch(self):
        return self.workspace.instance.custom_vm_arch

    BRAINFUCK_ID = 0
    BPF_ID = 1
    CYBERTRONIX_ID = 2
    AVR_ID = 3
    NEW_ARCH_ID = 4

    def handle_click_menu(self, idx):
        _l.warning("handle_click")

        if idx < 0 or idx >= len(self.MENU_BUTTONS):
            return

        mapping = {
            self.BRAINFUCK_ID: self.brainfuck,
            self.BPF_ID: self.bpf,
            self.CYBERTRONIX_ID: self.cybertronix,
            self.AVR_ID: self.avr,
            self.NEW_ARCH_ID: self.new_vm_arch,
        }

        mapping.get(idx)()

    # GRAPH_TRACE_LEGEND_WIDTH = 30
    # GRAPH_TRACE_LEGEND_SPACING = 20
    #
    # def draw_block(self, qblock: QBlock, painter: QPainter):
    #     _l.warning("draw_block")
    #     w = 5
    #     h = 5
    #     legend_x = 0 - self.GRAPH_TRACE_LEGEND_WIDTH - self.GRAPH_TRACE_LEGEND_SPACING
    #     painter.drawRect(legend_x, 0, w, h)

    def brainfuck(self):
        _l.warning("brainfuck")
        # view = self.workspace.view_manager.first_view_in_category('disassembly')
        # view.redraw_current_graph()
        # self.workspace.instance.add_job(LoadBinaryJob(file_path))

    def bpf(self):
        _l.warning("Berkeley Packet Filter (BPF)")

    def cybertronix(self):
        _l.warning("CyberTronix64k")

    def avr(self):
        _l.warning("Atmel AVR")

    def new_vm_arch(self):
        _l.warning("new_vm_arch")
        tfilter = 'json (*.json)'
        file_path, _ = QFileDialog.getOpenFileName(None, "Open the json file with arch info", "", tfilter)
        try:
            with open(file_path, 'rb') as f:
                f.read(1)
        except FileNotFoundError:
            return None




# GRAPH_TRACE_LEGEND_WIDTH = 30 # GRAPH_TRACE_LEGEND_SPACING = 20 # # def draw_block(self, qblock: QBlock, painter: QPainter): #     _l.warning("draw_block") #     w = 5 #     h = 5 #     legend_x = 0 - self.GRAPH_TRACE_LEGEND_WIDTH - self.GRAPH_TRACE_LEGEND_SPACING #     painter.drawRect(legend_x, 0, w, h) # view = self.workspace.view_manager.first_view_in_category('disassembly') # view.redraw_current_graph() # self.workspace.instance.add_job(LoadBinaryJob(file_path))