# -*- coding: utf-8 -*-
"""
    Custom GDB command for enabling default HW breakpoints.

 Copyright 2024 NXP

 NXP Confidential and Proprietary. This software is owned or controlled by NXP
 and may only be used strictly in accordance with the applicable license terms.
 By expressly accepting such terms or by downloading, installing, activating
 and/or otherwise using the software, you are agreeing that you have read, and
 that you agree to comply with and are bound by, such license terms. If you do
 not agree to be bound by the applicable license terms, then you may not retain,
 install, activate or otherwise use the software.
"""
import sys

class MemRegion:
    def __init__(self, enabled, low_addr, high_addr, attr, reg_id = -1):
        self.reg_id = reg_id
        self._enabled = enabled
        self._low_addr = low_addr
        self._high_addr = high_addr
        self._attr = attr


    def isInMemRegion(self, address):
        in_memory_region = False
        attribute = ""

        if self._enabled != "y":
            in_memory_region = False

        if address >= conv_to_int(self._low_addr) and address < conv_to_int(self._high_addr):
            in_memory_region = True
            # Check to see if there are some attributes for the current region, and if there are, pass them to the return statement.
            if self._attr:
                attribute = self._attr                
    
        return {
            "attribute": attribute,
            "in_memory_region": in_memory_region
        }

    def get_region_id(self):
        return self.reg_id
    
    def get_region_high_addr(self):
        return conv_to_int(self._high_addr)
    
    def get_region_low_addr(self):
        return conv_to_int(self._low_addr)
    
    def get_region_enabled(self):
        return self._enabled

    def get_region_attributes(self):
        if 'ro' in self._attr:
            return 'ro'
        if 'wo' in self._attr:
            return 'wo'
        if 'rw' in self._attr:
            return 'rw'
        else:
            return ''

    def getIntersection(self, start, end):
        if end <= conv_to_int(self._low_addr) or conv_to_int(self._high_addr) <= start:
            return []

        start_address = max(start, conv_to_int(self._low_addr))
        end_address = min(end, conv_to_int(self._high_addr))
        # Check to see if there are some attributes for the current region,
        # and if there are, pass them to the return statement.
        if self._attr:
            attribute = self._attr
        else:
            attribute = ""

        return {
            "start_address": start_address,
            "end_address": end_address,
            "access": True,
            "attribute": attribute
        }

    def print_region(self):
        print(
            self._enabled
            + "\t"
            + hex(conv_to_int(self._low_addr))
            + "\t"
            + hex(conv_to_int(self._high_addr))
            + "\t"
            + self._attr
            + "\n"
        )


def conv_to_int(num):
    # pylint: disable=all
    if sys.version_info.major == 2:
        if isinstance(num, str) or isinstance(num, unicode):
            if num.startswith("0x"):
                num = int(num, 16)
            else:
                num = int(num, 10)
        return num
    else:
        if isinstance(num, str):
            if num.startswith("0x"):
                num = int(num, 16)
            else:
                num = int(num, 10)
        return num