#!/usr/bin/python

# Python library with functions related to u-boot variables management

from subprocess import CalledProcessError
import lib_system
import lib_logger
import logging
import re

logger = logging.getLogger()

def get_uboot_value(name):
    '''
    Retrieve a u-boot variable
    @name: name of the u-boot variable to read
    Can raise a CalledProcessError exception
    '''
    try:
        (_, value) = lib_system.call_shell(["fw_printenv", "-n", name])
        return value
    except CalledProcessError as e:
        # Variable not found
        return None

def set_uboot_value(name, value):
    '''
    Set a u-boot variable
    @name: name of the u-boot variable to set
    @value: value to test as a string
    '''
    try:
        # Return code is 0 if variable found, 1 if not.
        lib_system.call_shell(["fw_setenv", name, value])
        return True
    except CalledProcessError as e:
        # Variable not found
        return False

def multiple_replace(dict, text):
    """ Replace in 'text' all occurences of any key in the given
    dictionary by its corresponding value.  Returns the new string.
    from http://code.activestate.com/recipes/81330-single-pass-multiple-replace/
    @dict: dictionary of { text_to_replace: replacement_text}
    @text: text that will be updated according to dictionary
    """

    # Create a regular expression  from the dictionary keys
    regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))

    # For each match, look-up corresponding value in dictionary
    return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)

def get_fdt_filename():
    '''
    According to u-boot version, the way to retrieve the fdt file name changed
    U-Boot version 2016.11 comes with Toradex 2.7
    U-Boot version 2015.04 comes with Toradex 2.6
    '''
    u_boot_version = get_uboot_value("ver")
    if "2016.11" in u_boot_version:
        return get_uboot_value("fdtfile")

    '''
    Retrieve the fdt filename from the fdt_file u-boot environment variable
    IF fdt_file u-boot variable is using other u-boot variables there are expanded.
    '''
    fdt_file = get_uboot_value("fdt_file")
    logger.debug("fdt_file value: {}".format(fdt_file))

    needed_variables = re.findall("\${(\w*)}",fdt_file)
    dict_needed_variables = {}
    for variable in needed_variables:
        dict_needed_variables["${" + variable + "}"] = get_uboot_value(variable)
    logger.debug("Needed value read from u-boot: {}".format(dict_needed_variables))

    fdt_file = multiple_replace(dict_needed_variables, fdt_file)
    logger.debug("fdt_file result: {}".format(fdt_file))
    return fdt_file

