# -*- coding: utf-8 -*-
"""
Device Tree Blob Parser

   Copyright 2014  Neil 'superna' Armstrong <superna9999@gmail.com>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

@author: Neil 'superna' Armstrong <superna9999@gmail.com>
"""

import string
import os
import json
from copy import deepcopy, copy
from struct import Struct, unpack, pack

FDT_MAGIC = 0xd00dfeed
FDT_BEGIN_NODE = 0x1
FDT_END_NODE = 0x2
FDT_PROP = 0x3
FDT_NOP = 0x4
FDT_END = 0x9

INDENT = ' ' * 4

FDT_MAX_VERSION = 17


class FdtProperty(object):
    """ Represents an empty property"""

    @staticmethod
    def __validate_dt_name(name):
        """Checks the name validity"""
        return not any([True for char in name
                        if char not in string.printable])

    def __init__(self, name):
        """Init with name"""
        self.name = name
        if not FdtProperty.__validate_dt_name(self.name):
            raise Exception("Invalid name '%s'" % self.name)

    def get_name(self):
        """Get property name"""
        return self.name

    def __str__(self):
        """String representation"""
        return "Property(%s)" % self.name

    def dts_represent(self, depth=0):
        """Get dts string representation"""
        return INDENT*depth + self.name + ';'

    def dtb_represent(self, string_store, pos=0, version=17):
        """Get blob representation"""
        # print "%x:%s" % (pos, self)
        strpos = string_store.find(self.name+'\0')
        if strpos < 0:
            strpos = len(string_store)
            string_store += self.name+'\0'
        pos += 12
        return (pack('>III', FDT_PROP, 0, strpos),
                string_store, pos)

    def json_represent(self, depth=0):
        """Ouput JSON"""
        return '%s: null' % json.dumps(self.name)

    def to_raw(self):
        """Return RAW value representation"""
        return ''

    def __getitem__(self, value):
        """Returns No Items"""
        return None

    def __ne__(self, node):
        """Check property inequality
        """
        return not self.__eq__(node)

    def __eq__(self, node):
        """Check node equality
           check properties are the same (same values)
        """
        if not isinstance(node, FdtProperty):
            raise Exception("Invalid object type")
        if self.name != node.get_name():
            return False
        return True

    @staticmethod
    def __check_prop_strings(value):
        """Check property string validity
           Python version of util_is_printable_string from dtc
        """
        pos = 0
        posi = 0
        end = len(value)

        if not len(value):
            return None

        #Needed for python 3 support: If a bytes object is passed,
        #decode it with the ascii codec. If the decoding fails, assume
        #it was not a string object.
        try:
            value = value.decode('ascii')
        except ValueError:
            return None

        #Test both against string 0 and int 0 because of
        # python2/3 compatibility
        if value[-1] != '\0':
            return None

        while pos < end:
            posi = pos
            while pos < end and value[pos] != '\0' \
                  and value[pos] in string.printable \
                  and value[pos] not in ('\r', '\n'):
                pos += 1

            if value[pos] != '\0' or pos == posi:
                return None
            pos += 1

        return True

    @staticmethod
    def new_raw_property(name, raw_value):
        """Instantiate property with raw value type"""
        if FdtProperty.__check_prop_strings(raw_value):
            return FdtPropertyStrings.init_raw(name, raw_value)
        elif len(raw_value) and len(raw_value) % 4 == 0:
            return FdtPropertyWords.init_raw(name, raw_value)
        elif len(raw_value) and len(raw_value):
            return FdtPropertyBytes.init_raw(name, raw_value)
        else:
            return FdtProperty(name)


class FdtPropertyStrings(FdtProperty):
    """Property with strings as value"""

    @classmethod
    def __extract_prop_strings(cls, value):
        """Extract strings from raw_value"""
        return [st for st in \
            value.decode('ascii').split('\0') if len(st)]

    def __init__(self, name, strings):
        """Init with strings"""
        FdtProperty.__init__(self, name)
        if not strings:
            raise Exception("Invalid strings")
        for stri in strings:
            if len(stri) == 0:
                raise Exception("Invalid strings")
            if any([True for char in stri
                        if char not in string.printable
                           or char in ('\r', '\n')]):
                raise Exception("Invalid chars in strings")
        self.strings = strings

    @classmethod
    def init_raw(cls, name, raw_value):
        """Init from raw"""
        return cls(name, cls.__extract_prop_strings(raw_value))

    def dts_represent(self, depth=0):
        """Get dts string representation"""
        return INDENT*depth + self.name + ' = "' + \
            '", "'.join(self.strings) + '";'

    def dtb_represent(self, string_store, pos=0, version=17):
        """Get blob representation"""
        # print "%x:%s" % (pos, self)
        blob = pack('')
        for chars in self.strings:
            blob += chars.encode('ascii') + pack('b', 0)
        blob_len = len(blob)
        if version < 16 and (pos+12) % 8 != 0:
            blob = pack('b', 0) * (8-((pos+12) % 8)) + blob
        if blob_len % 4:
            blob += pack('b', 0) * (4-(blob_len % 4))
        strpos = string_store.find(self.name+'\0')
        if strpos < 0:
            strpos = len(string_store)
            string_store += self.name+'\0'
        blob = pack('>III', FDT_PROP, blob_len, strpos) + blob
        pos += len(blob)
        return (blob, string_store, pos)

    def json_represent(self, depth=0):
        """Ouput JSON"""
        result = '%s: ["strings", ' % json.dumps(self.name)
        result += ', '.join([json.dumps(stri) for stri in self.strings])
        result += ']'
        return result

    def to_raw(self):
        """Return RAW value representation"""
        return ''.join([chars+'\0' for chars in self.strings])

    def __str__(self):
        """String representation"""
        return "Property(%s,Strings:%s)" % (self.name, self.strings)

    def __getitem__(self, index):
        """Get strings, returns a string"""
        return self.strings[index]

    def __len__(self):
        """Get strings count"""
        return len(self.strings)

    def __eq__(self, node):
        """Check node equality
           check properties are the same (same values)
        """
        if not FdtProperty.__eq__(self, node):
            return False
        if self.__len__() != len(node):
            return False
        for index in range(self.__len__()):
            if self.strings[index] != node[index]:
                return False
        return True

class FdtPropertyWords(FdtProperty):
    """Property with words as value"""

    def __init__(self, name, words):
        """Init with words"""
        FdtProperty.__init__(self, name)
        for word in words:
            if not 0 <= word <= 4294967295:
                raise Exception(("Invalid word value %d, requires " +
                                 "0 <= number <= 4294967295") % word)
        if not len(words):
            raise Exception("Invalid Words")
        self.words = words

    @classmethod
    def init_raw(cls, name, raw_value):
        """Init from raw"""
        if len(raw_value) % 4 == 0:
            words = [unpack(">I", raw_value[i:i+4])[0]
                     for i in range(0, len(raw_value), 4)]
            return cls(name, words)
        else:
            raise Exception("Invalid raw Words")

    def dts_represent(self, depth=0):
        """Get dts string representation"""
        return INDENT*depth + self.name + ' = <' + \
               ' '.join(["0x%08x" % word for word in self.words]) + ">;"

    def dtb_represent(self, string_store, pos=0, version=17):
        """Get blob representation"""
        # # print "%x:%s" % (pos, self)
        strpos = string_store.find(self.name+'\0')
        if strpos < 0:
            strpos = len(string_store)
            string_store += self.name+'\0'
        blob = pack('>III', FDT_PROP, len(self.words)*4, strpos) + \
                pack('').join([pack('>I', word) for word in self.words])
        pos += len(blob)
        return (blob, string_store, pos)

    def json_represent(self, depth=0):
        """Ouput JSON"""
        result = '%s: ["words", "' % json.dumps(self.name)
        result += '", "'.join(["0x%08x" % word for word in self.words])
        result += '"]'
        return result

    def to_raw(self):
        """Return RAW value representation"""
        return ''.join([pack('>I', word) for word in self.words])

    def __str__(self):
        """String representation"""
        return "Property(%s,Words:%s)" % (self.name, self.words)

    def __getitem__(self, index):
        """Get words, returns a word integer"""
        return self.words[index]

    def __len__(self):
        """Get words count"""
        return len(self.words)

    def __eq__(self, node):
        """Check node equality
           check properties are the same (same values)
        """
        if not FdtProperty.__eq__(self, node):
            return False
        if self.__len__() != len(node):
            return False
        for index in range(self.__len__()):
            if self.words[index] != node[index]:
                return False
        return True


class FdtPropertyBytes(FdtProperty):
    """Property with signed bytes as value"""

    def __init__(self, name, bytez):
        """Init with bytes"""
        FdtProperty.__init__(self, name)
        for byte in bytez:
            if not -128 <= byte <= 127:
                raise Exception(("Invalid value for byte %d, " +
                                 "requires -128 <= number <= 127") % byte)
        if not bytez:
            raise Exception("Invalid Bytes")
        self.bytes = bytez

    @classmethod
    def init_raw(cls, name, raw_value):
        """Init from raw"""
        return cls(name, unpack('b' * len(raw_value), raw_value))

    def dts_represent(self, depth=0):
        """Get dts string representation"""
        return INDENT*depth + self.name + ' = [' + \
            ' '.join(["%02x" % (byte & int('ffffffff',16))
                      for byte in self.bytes]) + "];"

    def dtb_represent(self, string_store, pos=0, version=17):
        """Get blob representation"""
        # print "%x:%s" % (pos, self)
        strpos = string_store.find(self.name+'\0')
        if strpos < 0:
            strpos = len(string_store)
            string_store += self.name+'\0'
        blob = pack('>III', FDT_PROP, len(self.bytes), strpos)
        blob += pack('').join([pack('>b', byte) for byte in self.bytes])
        if len(blob) % 4:
            blob += pack('b', 0) * (4-(len(blob) % 4))
        pos += len(blob)
        return (blob, string_store, pos)

    def json_represent(self, depth=0):
        """Ouput JSON"""
        result = '%s: ["bytes", "' % json.dumps(self.name)
        result += '", "'.join(["%02x" % byte
                                for byte in self.bytes])
        result += '"]'
        return result

    def to_raw(self):
        """Return RAW value representation"""
        return ''.join([pack('>b', byte) for byte in self.bytes])

    def __str__(self):
        """String representation"""
        return "Property(%s,Bytes:%s)" % (self.name, self.bytes)

    def __getitem__(self, index):
        """Get bytes, returns a byte"""
        return self.bytes[index]

    def __len__(self):
        """Get strings count"""
        return len(self.bytes)

    def __eq__(self, node):
        """Check node equality
           check properties are the same (same values)
        """
        if not FdtProperty.__eq__(self, node):
            return False
        if self.__len__() != len(node):
            return False
        for index in range(self.__len__()):
            if self.bytes[index] != node[index]:
                return False
        return True


class FdtNop(object):  # pylint: disable-msg=R0903
    """Nop child representation"""

    def __init__(self):
        """Init with nothing"""

    def get_name(self):  # pylint: disable-msg=R0201
        """Return name"""
        return None

    def __str__(self):
        """String representation"""
        return ''

    def dts_represent(self, depth=0):  # pylint: disable-msg=R0201
        """Get dts string representation"""
        return INDENT*depth+'// [NOP]'

    def dtb_represent(self, string_store, pos=0, version=17):
        """Get blob representation"""
        # print "%x:%s" % (pos, self)
        pos += 4
        return (pack('>I', FDT_NOP), string_store, pos)


class FdtNode(object):
    """Node representation"""

    @staticmethod
    def __validate_dt_name(name):
        """Checks the name validity"""
        return not any([True for char in name
                        if char not in string.printable])

    def __init__(self, name):
        """Init node with name"""
        self.name = name
        self.subdata = []
        self.parent = None
        if not FdtNode.__validate_dt_name(self.name):
            raise Exception("Invalid name '%s'" % self.name)

    def get_name(self):
        """Get property name"""
        return self.name

    def __check_name_duplicate(self, name):
        """Checks if name is not in a subnode"""
        for data in self.subdata:
            if not isinstance(data, FdtNop) \
               and data.get_name() == name:
                   return True
        return False

    def add_subnode(self, node):
        """Add child, deprecated use append()"""
        self.append(node)

    def add_raw_attribute(self, name, raw_value):
        """Construct a raw attribute and add to child"""
        self.append(FdtProperty.new_raw_property(name, raw_value))

    def set_parent_node(self, node):
        """Set parent node, None and FdtNode accepted"""
        if node is not None and \
           not isinstance(node, FdtNode):
            raise Exception("Invalid object type")
        self.parent = node

    def get_parent_node(self):
        """Get parent node"""
        return self.parent

    def __str__(self):
        """String representation"""
        return "Node(%s)" % self.name

    def dts_represent(self, depth=0):
        """Get dts string representation"""
        result = ('\n').join([sub.dts_represent(depth+1)
                                         for sub in self.subdata])
        if len(result) > 0:
            result += '\n'
        return INDENT*depth + self.name + ' {\n' + \
               result + INDENT*depth + "};"

    def dtb_represent(self, strings_store, pos=0, version=17):
        """Get blob representation
           Pass string storage as strings_store, pos for current node start
           and version as current dtb version
        """
        # print "%x:%s" % (pos, self)
        strings = strings_store
        if self.get_name() == '/':
            blob = pack('>II', FDT_BEGIN_NODE, 0)
        else:
            blob = pack('>I', FDT_BEGIN_NODE)
            blob += self.get_name().encode('ascii') + pack('b', 0)
        if len(blob) % 4:
            blob += pack('b', 0) * (4-(len(blob) % 4))
        pos += len(blob)
        for sub in self.subdata:
            (data, strings, pos) = sub.dtb_represent(strings, pos, version)
            blob += data
        pos += 4
        blob += pack('>I', FDT_END_NODE)
        return (blob, strings, pos)

    def json_represent(self, depth=0):
        """Get dts string representation"""
        result = (',\n'+ \
                  INDENT*(depth+1)).join([sub.json_represent(depth+1)
                                          for sub in self.subdata
                                          if not isinstance(sub, FdtNop)])
        if len(result) > 0:
            result = INDENT + result + '\n'+INDENT*depth
        if self.get_name() == '/':
            return "{\n" + INDENT*(depth) + result + "}"
        else:
            return json.dumps(self.name) + ': {\n' + \
                   INDENT*(depth) + result + "}"

    def __getitem__(self, index):
        """Get subnodes, returns either a Node, a Property or a Nop"""
        return self.subdata[index]

    def __setitem__(self, index, subnode):
        """Set node at index, replacing previous subnode,
           must not be a duplicate name
        """
        if self.subdata[index].get_name() != subnode.get_name() and \
           self.__check_name_duplicate(subnode.get_name()):
            raise Exception("%s : %s subnode already exists" % \
                                        (self, subnode))
        if not isinstance(subnode, (FdtNode, FdtProperty, FdtNop)):
            raise Exception("Invalid object type")
        self.subdata[index] = subnode

    def __len__(self):
        """Get strings count"""
        return len(self.subdata)

    def __ne__(self, node):
        """Check node inequality
           i.e. is subnodes are the same, in either order
           and properties are the same (same values)
           The FdtNop is excluded from the check
        """
        return not self.__eq__(node)

    def __eq__(self, node):
        """Check node equality
           i.e. is subnodes are the same, in either order
           and properties are the same (same values)
           The FdtNop is excluded from the check
        """
        if not isinstance(node, FdtNode):
            raise Exception("Invalid object type")
        if self.name != node.get_name():
            return False
        curnames = set([subnode.get_name() for subnode in self.subdata
                                    if not isinstance(subnode, FdtNop)])
        cmpnames = set([subnode.get_name() for subnode in node
                                    if not isinstance(subnode, FdtNop)])
        if curnames != cmpnames:
            return False
        for subnode in [subnode for subnode in self.subdata
                                    if not isinstance(subnode, FdtNop)]:
            index = node.index(subnode.get_name())
            if subnode != node[index]:
                return False
        return True

    def append(self, subnode):
        """Append subnode, same as add_subnode"""
        if self.__check_name_duplicate(subnode.get_name()):
            raise Exception("%s : %s subnode already exists" % \
                                    (self, subnode))
        if not isinstance(subnode, (FdtNode, FdtProperty, FdtNop)):
            raise Exception("Invalid object type")
        self.subdata.append(subnode)

    def pop(self, index=-1):
        """Remove and returns subnode at index, default the last"""
        return self.subdata.pop(index)

    def insert(self, index, subnode):
        """Insert subnode before index, must not be a duplicate name"""
        if self.__check_name_duplicate(subnode.get_name()):
            raise Exception("%s : %s subnode already exists" % \
                                (self, subnode))
        if not isinstance(subnode, (FdtNode, FdtProperty, FdtNop)):
            raise Exception("Invalid object type")
        self.subdata.insert(index, subnode)

    def _find(self, name):
        """Find name in subnodes"""
        for i in range(0, len(self.subdata)):
            if not isinstance(self.subdata[i], FdtNop) and \
               name == self.subdata[i].get_name():
                return i
        return None

    def remove(self, name):
        """Remove subnode with the name
           Raises ValueError is not present
        """
        index = self._find(name)
        if index is None:
            raise ValueError("Not present")
        return self.subdata.pop(index)

    def index(self, name):
        """Returns position of subnode with the name
           Raises ValueError is not present
        """
        index = self._find(name)
        if index is None:
            raise ValueError("Not present")
        return index

    def merge(self, node):
        """Merge two nodes and subnodes
           Replace current properties with the given properties
        """
        if not isinstance(node, FdtNode):
            raise Exception("Can only merge with a FdtNode")
        for subnode in [obj for obj in node
                        if isinstance(obj, (FdtNode, FdtProperty))]:
            index = self._find(subnode.get_name())
            if index is None:
                dup = deepcopy(subnode)
                if isinstance(subnode, FdtNode):
                    dup.set_parent_node(self)
                self.append(dup)
            elif isinstance(subnode, FdtNode):
                self.subdata[index].merge(subnode)
            else:
                self.subdata[index] = copy(subnode)

    def walk(self):
        """Walk into subnodes and yield paths and objects
           Returns set with (path string, node object)
        """
        node = self
        start = 0
        hist = []
        curpath = []

        while True:
            for index in range(start, len(node)):
                if isinstance(node[index], (FdtNode, FdtProperty)):
                    yield ('/' + '/'.join(curpath+[node[index].get_name()]),
                            node[index])
                if isinstance(node[index], FdtNode):
                    if len(node[index]):
                        hist.append((node, index+1))
                        curpath.append(node[index].get_name())
                        node = node[index]
                        start = 0
                        index = -1
                        break
            if index >= 0:
                if len(hist):
                    (node, start) = hist.pop()
                    curpath.pop()
                else:
                    break


class Fdt(object):
    """Flattened Device Tree representation"""

    def __init__(self, version=17, last_comp_version=16, boot_cpuid_phys=0):
        """Init FDT object with version and boot values"""
        self.header = {'magic': FDT_MAGIC,
                       'totalsize': 0,
                       'off_dt_struct': 0,
                       'off_dt_strings': 0,
                       'off_mem_rsvmap': 0,
                       'version': version,
                       'last_comp_version': last_comp_version,
                       'boot_cpuid_phys': boot_cpuid_phys,
                       'size_dt_strings': 0,
                       'size_dt_struct': 0}
        self.rootnode = None
        self.prenops = None
        self.postnops = None
        self.reserve_entries = None

    def add_rootnode(self, rootnode, prenops=None, postnops=None):
        """Add root node"""
        self.rootnode = rootnode
        self.prenops = prenops
        self.postnops = postnops

    def get_rootnode(self):
        """Get root node"""
        return self.rootnode

    def add_reserve_entries(self, reserve_entries):
        """Add reserved entries as list of dict with
           'address' and 'size' keys"""
        self.reserve_entries = reserve_entries

    def to_dts(self):
        """Export to DTS representation in string format"""
        result = "/dts-v1/;\n"
        result += "// version:\t\t%d\n" % self.header['version']
        result += "// last_comp_version:\t%d\n" % \
                  self.header['last_comp_version']
        if self.header['version'] >= 2:
            result += "// boot_cpuid_phys:\t0x%x\n" % \
                self.header['boot_cpuid_phys']
        result += '\n'
        if self.reserve_entries is not None:
            for entry in self.reserve_entries:
                result += "/memreserve/ "
                if entry['address']:
                    result += "%#x " % entry['address']
                else:
                    result += "0 "
                if entry['size']:
                    result += "%#x" % entry['size']
                else:
                    result += "0"
                result += ";\n"
        if self.prenops:
            result += '\n'.join([nop.dts_represent() for nop in self.prenops])
            result += '\n'
        if self.rootnode is not None:
            result += self.rootnode.dts_represent()
        if self.postnops:
            result += '\n'
            result += '\n'.join([nop.dts_represent() for nop in self.postnops])
        return result

    def to_dtb(self):
        """Export to Blob format"""
        if self.rootnode is None:
            return None
        blob_reserve_entries = pack('')
        if self.reserve_entries is not None:
            for entry in self.reserve_entries:
                blob_reserve_entries += pack('>QQ',
                                             entry['address'],
                                             entry['size'])
        blob_reserve_entries += pack('>QQ', 0, 0)
        header_size = 7 * 4
        if self.header['version'] >= 2:
            header_size += 4
        if self.header['version'] >= 3:
            header_size += 4
        if self.header['version'] >= 17:
            header_size += 4
        header_adjust = pack('')
        if header_size % 8 != 0:
            header_adjust = pack('b', 0) * (8 - (header_size % 8))
            header_size += len(header_adjust)
        dt_start = header_size + len(blob_reserve_entries)
        # print "dt_start %d" % dt_start
        (blob_dt, blob_strings, dt_pos) = \
            self.rootnode.dtb_represent('', dt_start, self.header['version'])
        if self.prenops is not None:
            blob_dt = pack('').join([nop.dtb_represent('')[0]
                               for nop in self.prenops])\
                      + blob_dt
        if self.postnops is not None:
            blob_dt += pack('').join([nop.dtb_represent('')[0]
                                for nop in self.postnops])
        blob_dt += pack('>I', FDT_END)
        self.header['size_dt_strings'] = len(blob_strings)
        self.header['size_dt_struct'] = len(blob_dt)
        self.header['off_mem_rsvmap'] = header_size
        self.header['off_dt_struct'] = dt_start
        self.header['off_dt_strings'] = dt_start + len(blob_dt)
        self.header['totalsize'] = dt_start + len(blob_dt) + len(blob_strings)
        blob_header = pack('>IIIIIII', self.header['magic'],
                           self.header['totalsize'],
                           self.header['off_dt_struct'],
                           self.header['off_dt_strings'],
                           self.header['off_mem_rsvmap'],
                           self.header['version'],
                           self.header['last_comp_version'])
        if self.header['version'] >= 2:
            blob_header += pack('>I', self.header['boot_cpuid_phys'])
        if self.header['version'] >= 3:
            blob_header += pack('>I', self.header['size_dt_strings'])
        if self.header['version'] >= 17:
            blob_header += pack('>I', self.header['size_dt_struct'])
        return blob_header + header_adjust + blob_reserve_entries + \
            blob_dt + blob_strings.encode('ascii')

    def to_json(self):
        """Ouput JSON"""
        if self.rootnode is None:
            return None
        return self.rootnode.json_represent()

    def resolve_path(self, path):
        """Resolve path like /memory/reg and return either a FdtNode,
            a FdtProperty or None"""
        if self.rootnode is None:
            return None
        if not path.startswith('/'):
            return None
        if len(path) > 1 and path.endswith('/'):
            path = path[:-1]
        if path == '/':
            return self.rootnode
        curnode = self.rootnode
        for subpath in path[1:].split('/'):
            found = None
            if not isinstance(curnode, FdtNode):
                return None
            for node in curnode:
                if subpath == node.get_name():
                    found = node
                    break
            if found is None:
                return None
            curnode = found
        return curnode

def _add_json_to_fdtnode(node, subjson):
    """Populate FdtNode with JSON dict items"""
    for (key, value) in subjson.items():
        if isinstance(value, dict):
            subnode = FdtNode(key)
            subnode.set_parent_node(node)
            node.append(subnode)
            _add_json_to_fdtnode(subnode, value)
        elif isinstance(value, list):
            if len(value) < 2:
                raise Exception("Invalid list for %s" % key)
            if value[0] == "words":
                words = [int(word, 16) for word in value[1:]]
                node.append(FdtPropertyWords(key, words))
            elif value[0] == "bytes":
                bytez = [int(byte, 16) for byte in value[1:]]
                node.append(FdtPropertyBytes(key, bytez))
            elif value[0] == "strings":
                node.append(FdtPropertyStrings(key, \
                            [s for s in value[1:]]))
            else:
                raise Exception("Invalid list for %s" % key)
        elif value is None:
            node.append(FdtProperty(key))
        else:
            raise Exception("Invalid value for %s" % key)

def FdtJsonParse(buf):
    """Import FDT from JSON representation, see JSONDeviceTree.md for
       structure and encoding
       Returns an Fdt object
    """
    tree = json.loads(buf)

    root = FdtNode('/')

    _add_json_to_fdtnode(root, tree)

    fdt = Fdt()
    fdt.add_rootnode(root)
    return fdt

def FdtFsParse(path):
    """Parse device tree filesystem and return a Fdt instance
       Should be /proc/device-tree on a device, or the fusemount.py
       mount point.
    """
    root = FdtNode("/")

    if path.endswith('/'):
        path = path[:-1]

    nodes = {path: root}

    for subpath, subdirs, files in os.walk(path):
        if subpath not in nodes.keys():
            raise Exception("os.walk error")
        cur = nodes[subpath]
        for f in files:
            with open(subpath+'/'+f, 'rb') as content_file:
                content = content_file.read()
            prop = FdtProperty.new_raw_property(f, content)
            cur.add_subnode(prop)
        for subdir in subdirs:
            subnode = FdtNode(subdir)
            cur.add_subnode(subnode)
            subnode.set_parent_node(cur)
            nodes[subpath+'/'+subdir] = subnode

    fdt = Fdt()
    fdt.add_rootnode(root)
    return fdt

class FdtBlobParse(object):  # pylint: disable-msg=R0903
    """Parse from file input"""

    __fdt_header_format = ">IIIIIII"
    __fdt_header_names = ('magic', 'totalsize', 'off_dt_struct',
                          'off_dt_strings', 'off_mem_rsvmap', 'version',
                          'last_comp_version')

    __fdt_reserve_entry_format = ">QQ"
    __fdt_reserve_entry_names = ('address', 'size')

    __fdt_dt_cell_format = ">I"
    __fdt_dt_prop_format = ">II"
    __fdt_dt_tag_name = {FDT_BEGIN_NODE: 'node_begin',
                         FDT_END_NODE: 'node_end',
                         FDT_PROP: 'prop',
                         FDT_NOP: 'nop',
                         FDT_END: 'end'}

    def __extract_fdt_header(self):
        """Extract DTB header"""
        header = Struct(self.__fdt_header_format)
        header_entry = Struct(">I")
        data = self.infile.read(header.size)
        result = dict(zip(self.__fdt_header_names, header.unpack_from(data)))
        if result['version'] >= 2:
            data = self.infile.read(header_entry.size)
            result['boot_cpuid_phys'] = header_entry.unpack_from(data)[0]
        if result['version'] >= 3:
            data = self.infile.read(header_entry.size)
            result['size_dt_strings'] = header_entry.unpack_from(data)[0]
        if result['version'] >= 17:
            data = self.infile.read(header_entry.size)
            result['size_dt_struct'] = header_entry.unpack_from(data)[0]
        return result

    def __extract_fdt_reserve_entries(self):
        """Extract reserved memory entries"""
        header = Struct(self.__fdt_reserve_entry_format)
        entries = []
        self.infile.seek(self.fdt_header['off_mem_rsvmap'])
        while True:
            data = self.infile.read(header.size)
            result = dict(zip(self.__fdt_reserve_entry_names,
                              header.unpack_from(data)))
            if result['address'] == 0 and result['size'] == 0:
                return entries
            entries.append(result)

    def __extract_fdt_nodename(self):
        """Extract node name"""
        data = ''
        pos = self.infile.tell()
        while True:
            byte = self.infile.read(1)
            if ord(byte) == 0:
                break
            data += byte.decode('ascii')
        align_pos = pos + len(data) + 1
        align_pos = (((align_pos) + ((4) - 1)) & ~((4) - 1))
        self.infile.seek(align_pos)
        return data

    def __extract_fdt_string(self, prop_string_pos):
        """Extract string from string pool"""
        data = ''
        pos = self.infile.tell()
        self.infile.seek(self.fdt_header['off_dt_strings']+prop_string_pos)
        while True:
            byte = self.infile.read(1)
            if ord(byte) == 0:
                break
            data += byte.decode('ascii')
        self.infile.seek(pos)
        return data

    def __extract_fdt_prop(self):
        """Extract property"""
        prop = Struct(self.__fdt_dt_prop_format)
        pos = self.infile.tell()
        data = self.infile.read(prop.size)
        (prop_size, prop_string_pos,) = prop.unpack_from(data)

        prop_start = pos + prop.size
        if self.fdt_header['version'] < 16 and prop_size >= 8:
            prop_start = (((prop_start) + ((8) - 1)) & ~((8) - 1))

        self.infile.seek(prop_start)
        value = self.infile.read(prop_size)

        align_pos = self.infile.tell()
        align_pos = (((align_pos) + ((4) - 1)) & ~((4) - 1))
        self.infile.seek(align_pos)

        return (self.__extract_fdt_string(prop_string_pos), value)

    def __extract_fdt_dt(self):
        """Extract tags"""
        cell = Struct(self.__fdt_dt_cell_format)
        tags = []
        self.infile.seek(self.fdt_header['off_dt_struct'])
        while True:
            data = self.infile.read(cell.size)
            if len(data) < cell.size:
                break
            tag, = cell.unpack_from(data)
            # print "*** %s" % self.__fdt_dt_tag_name.get(tag, '')
            if self.__fdt_dt_tag_name.get(tag, '') in 'node_begin':
                name = self.__extract_fdt_nodename()
                if len(name) == 0:
                    name = '/'
                tags.append((tag, name))
            elif self.__fdt_dt_tag_name.get(tag, '') in ('node_end', 'nop'):
                tags.append((tag, ''))
            elif self.__fdt_dt_tag_name.get(tag, '') in 'end':
                tags.append((tag, ''))
                break
            elif self.__fdt_dt_tag_name.get(tag, '') in 'prop':
                propdata = self.__extract_fdt_prop()
                tags.append((tag, propdata))
            else:
                print("Unknown Tag %d" % tag)
        return tags

    def __init__(self, infile):
        """Init with file input"""
        self.infile = infile
        self.fdt_header = self.__extract_fdt_header()
        if self.fdt_header['magic'] != FDT_MAGIC:
            raise Exception('Invalid Magic')
        if self.fdt_header['version'] > FDT_MAX_VERSION:
            raise Exception('Invalid Version %d' % self.fdt_header['version'])
        if self.fdt_header['last_comp_version'] > FDT_MAX_VERSION-1:
            raise Exception('Invalid last compatible Version %d' %
                            self.fdt_header['last_comp_version'])
        self.fdt_reserve_entries = self.__extract_fdt_reserve_entries()
        self.fdt_dt_tags = self.__extract_fdt_dt()

    def __to_nodes(self):
        """Represent fdt as Node and properties structure
           Returns a set with the pre-node Nops, the Root Node,
            and the post-node Nops.
        """
        prenops = []
        postnops = []
        rootnode = None
        curnode = None
        for tag in self.fdt_dt_tags:
            if self.__fdt_dt_tag_name.get(tag[0], '') in 'node_begin':
                newnode = FdtNode(tag[1])
                if rootnode is None:
                    rootnode = newnode
                if curnode is not None:
                    curnode.add_subnode(newnode)
                    newnode.set_parent_node(curnode)
                curnode = newnode
            elif self.__fdt_dt_tag_name.get(tag[0], '') in 'node_end':
                if curnode is not None:
                    curnode = curnode.get_parent_node()
            elif self.__fdt_dt_tag_name.get(tag[0], '') in 'nop':
                if curnode is not None:
                    curnode.add_subnode(FdtNop())
                elif rootnode is not None:
                    postnops.append(FdtNop())
                else:
                    prenops.append(FdtNop())
            elif self.__fdt_dt_tag_name.get(tag[0], '') in 'prop':
                if curnode is not None:
                    curnode.add_raw_attribute(tag[1][0], tag[1][1])
            elif self.__fdt_dt_tag_name.get(tag[0], '') in 'end':
                continue
        return (prenops, rootnode, postnops)

    def to_fdt(self):
        """Create a fdt object
            Returns a Fdt object
        """
        if self.fdt_header['version'] >= 2:
            boot_cpuid_phys = self.fdt_header['boot_cpuid_phys']
        else:
            boot_cpuid_phys = 0
        fdt = Fdt(version=self.fdt_header['version'],
                  last_comp_version=self.fdt_header['last_comp_version'],
                  boot_cpuid_phys=boot_cpuid_phys)
        (prenops, rootnode, postnops) = self.__to_nodes()
        fdt.add_rootnode(rootnode, prenops=prenops, postnops=postnops)
        fdt.add_reserve_entries(self.fdt_reserve_entries)
        return fdt
