#
# Copyright (c) 2017 Linaro
# Copyright (c) 2017 Bobby Noelte
#
# SPDX-License-Identifier: Apache-2.0
#

import sys

from collections import defaultdict

# globals
phandles = {}
aliases = defaultdict(list)
chosen = {}
reduced = {}
defs = {}
bindings = {}
bus_bindings = {}
binding_compats = []
old_alias_names = False

regs_config = {
    'zephyr,sram'  : 'DT_SRAM',
    'zephyr,ccm'   : 'DT_CCM'
}

name_config = {
    'zephyr,console'     : 'DT_UART_CONSOLE_ON_DEV_NAME',
    'zephyr,shell-uart'  : 'DT_UART_SHELL_ON_DEV_NAME',
    'zephyr,bt-uart'     : 'DT_BT_UART_ON_DEV_NAME',
    'zephyr,uart-pipe'   : 'DT_UART_PIPE_ON_DEV_NAME',
    'zephyr,bt-mon-uart' : 'DT_BT_MONITOR_ON_DEV_NAME',
    'zephyr,uart-mcumgr' : 'DT_UART_MCUMGR_ON_DEV_NAME'
}


def str_to_label(s):
    # Change ,-@/ to _ and uppercase
    return s.replace('-', '_') \
            .replace(',', '_') \
            .replace('@', '_') \
            .replace('/', '_') \
            .upper()


def all_compats(node):
    # Returns a set() of all 'compatible' strings that appear at or below
    # 'node', skipping disabled nodes

    if node['props'].get('status') == 'disabled':
        return set()

    compats = set()

    if 'compatible' in node['props']:
        val = node['props']['compatible']
        if isinstance(val, list):
            compats.update(val)
        else:
            compats.add(val)

    for child_node in node['children'].values():
        compats.update(all_compats(child_node))

    return compats


def create_aliases(root):
    if 'aliases' in root['children']:
        for name, node_path in root['children']['aliases']['props'].items():
            aliases[node_path].append(name)

    # Treat alternate names as aliases
    for node_path, node in reduced.items():
        if 'alt_name' in node:
            aliases[node_path].append(node['alt_name'])


def get_compat(node_path):
    # Returns the value of the 'compatible' property for the node at
    # 'node_path'. Also checks the node's parent.
    #
    # Returns None if neither the node nor its parent has a 'compatible'
    # property.

    compat = reduced[node_path]['props'].get('compatible') or \
             reduced[get_parent_path(node_path)]['props'].get('compatible')

    if isinstance(compat, list):
        return compat[0]

    return compat


def create_chosen(root):
    if 'chosen' in root['children']:
        chosen.update(root['children']['chosen']['props'])


def create_phandles(root, name):
    if root['props'].get('status') == 'disabled':
        return

    if 'phandle' in root['props']:
        phandles[root['props']['phandle']] = name

    if name != '/':
        name += '/'

    for child_name, child_node in root['children'].items():
        create_phandles(child_node, name + child_name)


def insert_defs(node_path, new_defs, new_aliases):
    for key in new_defs:
        if key.startswith('DT_COMPAT_'):
            node_path = 'compatibles'

    remove = [k for k in new_aliases if k in new_defs]
    for k in remove: del new_aliases[k]

    if node_path in defs:
        remove = [k for k in new_aliases if k in defs[node_path]]
        for k in remove: del new_aliases[k]
        defs[node_path]['aliases'].update(new_aliases)
        defs[node_path].update(new_defs)
    else:
        new_defs['aliases'] = new_aliases
        defs[node_path] = new_defs


# Dictionary where all keys default to 0. Used by create_reduced().
last_used_id = defaultdict(int)


def create_reduced(node, path):
    # Compress nodes list to nodes w/ paths, add interrupt parent

    if node['props'].get('status') == 'disabled':
        return

    reduced[path] = node.copy()
    reduced[path].pop('children', None)

    # Assign an instance ID for each compat
    compat = node['props'].get('compatible')
    if compat:
        if type(compat) is not list:
            compat = [compat]

        reduced[path]['instance_id'] = {}
        for comp in compat:
            reduced[path]['instance_id'][comp] = last_used_id[comp]
            last_used_id[comp] += 1

    # Flatten 'prop = <1 2>, <3 4>' (which turns into nested lists) to
    # 'prop = <1 2 3 4>'
    for val in node['props'].values():
        if isinstance(val, list) and isinstance(val[0], list):
            # In-place modification
            val[:] = [item for sublist in val for item in sublist]

    if node['children']:
        if path != '/':
            path += '/'

        for child_name, child_node in sorted(node['children'].items()):
            create_reduced(child_node, path + child_name)


def node_label(node_path):
    node_compat = get_compat(node_path)
    def_label = str_to_label(node_compat)
    if '@' in node_path:
        # See if we have number we can convert
        try:
            unit_addr = int(node_path.split('@')[-1], 16)
            (nr_addr_cells, nr_size_cells) = get_addr_size_cells(node_path)
            unit_addr += translate_addr(unit_addr, node_path,
                         nr_addr_cells, nr_size_cells)
            unit_addr = "%x" % unit_addr
        except:
            unit_addr = node_path.split('@')[-1]
        def_label += '_' + str_to_label(unit_addr)
    else:
        def_label += '_' + str_to_label(node_path.split('/')[-1])
    return def_label


def get_parent_path(node_path):
    # Turns /foo/bar into /foo. Returns None for /.

    if node_path == '/':
        return None

    return '/'.join(node_path.split('/')[:-1]) or '/'


def find_parent_prop(node_path, prop):
    parent_path = get_parent_path(node_path)

    if prop not in reduced[parent_path]['props']:
        raise Exception("Parent of node " + node_path +
                        " has no " + prop + " property")

    return reduced[parent_path]['props'][prop]


# Get the #{address,size}-cells for a given node
def get_addr_size_cells(node_path):
    parent_addr = get_parent_path(node_path)

    # The DT spec says that if #address-cells is missing default to 2
    # if #size-cells is missing default to 1
    nr_addr = reduced[parent_addr]['props'].get('#address-cells', 2)
    nr_size = reduced[parent_addr]['props'].get('#size-cells', 1)

    return (nr_addr, nr_size)

def translate_addr(addr, node_path, nr_addr_cells, nr_size_cells):
    parent_path = get_parent_path(node_path)

    ranges = reduced[parent_path]['props'].get('ranges')
    if not ranges:
        return 0

    if isinstance(ranges, list):
        ranges = ranges.copy()  # Modified in-place below
    else:
        # Empty value ('ranges;'), meaning the parent and child address spaces
        # are the same
        ranges = []

    nr_p_addr_cells, nr_p_size_cells = get_addr_size_cells(parent_path)

    range_offset = 0
    while ranges:
        child_bus_addr = 0
        parent_bus_addr = 0
        range_len = 0
        for x in range(nr_addr_cells):
            val = ranges.pop(0) << (32 * (nr_addr_cells - x - 1))
            child_bus_addr += val
        for x in range(nr_p_addr_cells):
            val = ranges.pop(0) << (32 * (nr_p_addr_cells - x - 1))
            parent_bus_addr += val
        for x in range(nr_size_cells):
            range_len += ranges.pop(0) << (32 * (nr_size_cells - x - 1))
        # if we are outside of the range we don't need to translate
        if child_bus_addr <= addr <= (child_bus_addr + range_len):
            range_offset = parent_bus_addr - child_bus_addr
            break

    parent_range_offset = translate_addr(addr + range_offset,
            parent_path, nr_p_addr_cells, nr_p_size_cells)
    range_offset += parent_range_offset

    return range_offset

def enable_old_alias_names(enable):
    global old_alias_names
    old_alias_names = enable

def add_compat_alias(node_path, label_postfix, label, prop_aliases):
    if 'instance_id' in reduced[node_path]:
        instance = reduced[node_path]['instance_id']
        for k in instance:
            i = instance[k]
            b = 'DT_' + str_to_label(k) + '_' + str(i) + '_' + label_postfix
            prop_aliases[b] = label

def add_prop_aliases(node_path,
                     alias_label_function, prop_label, prop_aliases):
    node_compat = get_compat(node_path)
    new_alias_prefix = 'DT_' + str_to_label(node_compat)

    for alias in aliases[node_path]:
        old_alias_label = alias_label_function(alias)
        new_alias_label = new_alias_prefix + '_' + old_alias_label

        if new_alias_label != prop_label:
            prop_aliases[new_alias_label] = prop_label
        if old_alias_names and old_alias_label != prop_label:
            prop_aliases[old_alias_label] = prop_label

def get_binding(node_path):
    compat = get_compat(node_path)

    # For just look for the binding in the main dict
    # if we find it here, return it, otherwise it best
    # be in the bus specific dict
    if compat in bindings:
        return bindings[compat]

    parent_path = get_parent_path(node_path)
    parent_compat = get_compat(parent_path)

    parent_binding = bindings[parent_compat]

    bus = parent_binding['child']['bus']
    binding = bus_bindings[bus][compat]

    return binding

def get_binding_compats():
    return binding_compats

def build_cell_array(prop_array):
    index = 0
    ret_array = []

    while index < len(prop_array):
        handle = prop_array[index]

        if handle in {0, -1}:
            ret_array.append([])
            index += 1
        else:
            # get controller node (referenced via phandle)
            cell_parent = phandles[handle]

            for prop in reduced[cell_parent]['props']:
                if prop[0] == '#' and '-cells' in prop:
                    num_cells = reduced[cell_parent]['props'][prop]
                    break

            ret_array.append(prop_array[index:index+num_cells+1])

            index += num_cells + 1

    return ret_array


def extract_controller(node_path, prop, prop_values, index,
                       def_label, generic, handle_single=False):

    prop_def = {}
    prop_alias = {}

    prop_array = build_cell_array(prop_values)
    if handle_single:
        prop_array = [prop_array[index]]

    for i, elem in enumerate(prop_array):
        num_cells = len(elem)

        # if the entry is empty, skip
        if num_cells == 0:
            continue

        cell_parent = phandles[elem[0]]
        l_cell = reduced[cell_parent]['props'].get('label')

        if l_cell is None:
            continue

        l_base = [def_label]

        # Check is defined should be indexed (_0, _1)
        if handle_single or i == 0 and len(prop_array) == 1:
            # 0 or 1 element in prop_values
            l_idx = []
        else:
            l_idx = [str(i)]

        # Check node generation requirements
        try:
            generation = get_binding(node_path)['properties'
                    ][prop]['generation']
        except:
            generation = ''

        if 'use-prop-name' in generation:
            l_cellname = str_to_label(prop + '_' + 'controller')
        else:
            l_cellname = str_to_label(generic + '_' + 'controller')

        label = l_base + [l_cellname] + l_idx

        add_compat_alias(node_path, '_'.join(label[1:]), '_'.join(label), prop_alias)
        prop_def['_'.join(label)] = "\"" + l_cell + "\""

        #generate defs also if node is referenced as an alias in dts
        if node_path in aliases:
            add_prop_aliases(
                node_path,
                lambda alias: '_'.join([str_to_label(alias)] + label[1:]),
                '_'.join(label),
                prop_alias)

        insert_defs(node_path, prop_def, prop_alias)


def extract_cells(node_path, prop, prop_values, names, index,
                  def_label, generic, handle_single=False):

    prop_array = build_cell_array(prop_values)
    if handle_single:
        prop_array = [prop_array[index]]

    for i, elem in enumerate(prop_array):
        num_cells = len(elem)

        # if the entry is empty, skip
        if num_cells == 0:
            continue

        cell_parent = phandles[elem[0]]

        try:
            cell_yaml = get_binding(cell_parent)
        except:
            raise Exception(
                "Could not find yaml description for " +
                    reduced[cell_parent]['name'])

        try:
            name = names.pop(0).upper()
        except:
            name = ''

        # Get number of cells per element of current property
        for props in reduced[cell_parent]['props']:
            if props[0] == '#' and '-cells' in props:
                if props in cell_yaml:
                    cell_yaml_names = props
                else:
                    cell_yaml_names = '#cells'
        try:
            generation = get_binding(node_path)['properties'][prop
                    ]['generation']
        except:
            generation = ''

        if 'use-prop-name' in generation:
            l_cell = [str_to_label(str(prop))]
        else:
            l_cell = [str_to_label(str(generic))]

        l_base = [def_label]
        # Check if #define should be indexed (_0, _1, ...)
        if handle_single or i == 0 and len(prop_array) == 1:
            # Less than 2 elements in prop_values
            # Indexing is not needed
            l_idx = []
        else:
            l_idx = [str(i)]

        prop_def = {}
        prop_alias = {}

        # Generate label for each field of the property element
        for j in range(num_cells-1):
            l_cellname = [str(cell_yaml[cell_yaml_names][j]).upper()]
            if l_cell == l_cellname:
                label = l_base + l_cell + l_idx
            else:
                label = l_base + l_cell + l_cellname + l_idx
            label_name = l_base + [name] + l_cellname
            add_compat_alias(node_path, '_'.join(label[1:]), '_'.join(label), prop_alias)
            prop_def['_'.join(label)] = elem[j+1]
            if name:
                prop_alias['_'.join(label_name)] = '_'.join(label)

            # generate defs for node aliases
            if node_path in aliases:
                add_prop_aliases(
                    node_path,
                    lambda alias: '_'.join([str_to_label(alias)] + label[1:]),
                    '_'.join(label),
                    prop_alias)

            insert_defs(node_path, prop_def, prop_alias)


def err(msg):
    # General error reporting helper. Prints a message to stderr and exits with
    # status 1.

    sys.exit("error: " + msg)
