#!/usr/bin/python
#
# Copyright (c) 2017 Intel Corporation
#
# 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.
#

import sys
import pprint

def read_until(line, fd, end):
  out = [line]
  while True:
    idx = line.find(end)
    if idx < 0:
      line = clean_line(fd.readline(), fd)
      out.append(line)
    else:
      out.append(line[idx + len(end):])
      return out

def remove_comment(line, fd):
  out = []
  while True:
    idx = line.find('/*')
    if idx < 0:
      idx = line.find('//')
      if idx < 0:
        out.append(line)
      else:
        out.append(line[:idx])
      return ' '.join(out)

    out.append(line[:idx])
    line = read_until(line[idx:], fd, '*/')[-1]

def clean_line(line, fd):
  return remove_comment(line, fd).strip()

def parse_node_name(line):
  line = line[:-1]

  if '@' in line:
    line, addr = line.split('@')
  else:
    addr = None

  if ':' in line:
    label, name = line.split(':')
  else:
    name = line
    label = None

  if addr is None:
    return label, name.strip(), None

  return label, name.strip(), int(addr, 16)

def parse_values_internal(value, start, end, separator):
  out = []

  inside = False
  accum = []
  for ch in value:
    if not inside:
      if ch == start:
        inside = True
        accum = []
    else:
      if ch == end:
        inside = False
        out.append(''.join(accum))
        accum = []
      else:
        accum.append(ch)

  if separator == ' ':
    out = [v.split() for v in out]

  if len(out) == 1:
    return parse_value(out[0])

  return [parse_value(v) for v in out]

def parse_values(value, start, end, separator):
  out = parse_values_internal(value, start, end, separator)
  if isinstance(out, list) and all(isinstance(v, str) and len(v) == 1 and not v.isalpha() for v in out):
    return bytearray(out)
  return out

def parse_value(value):
  if value == '':
    return value

  if isinstance(value, list):
    out = [parse_value(v) for v in value]
    return out[0] if len(out) == 1 else out

  if value[0] == '<':
    return parse_values(value, '<', '>', ' ')
  if value[0] == '"':
    return parse_values(value, '"', '"', ',')
  if value[0] == '[':
    return parse_values(value, '[', ']', ' ')

  if value[0] == '&':
    return {'ref': value[1:]}

  if value[0].isdigit():
    if value.startswith("0x"):
      return int(value, 16)
    if value[0] == '0':
      return int(value, 8)
    return int(value, 10)

  return value

def parse_property(property, fd):
  if '=' in property:
    key, value = property.split('=', 1)
    value = ' '.join(read_until(value, fd, ';')).strip()
    if not value.endswith(';'):
      raise SyntaxError("parse_property: missing semicolon: %s" % value)
    return key.strip(), parse_value(value[:-1])

  property = property.strip()
  if not property.endswith(';'):
    raise SyntaxError("parse_property: missing semicolon: %s" % property)

  return property[:-1].strip(), True

def build_node_name(name, addr):
  if addr is None:
    return name
  return '%s@%x' % (name, addr)

def parse_node(line, fd):
  label, name, addr = parse_node_name(line)

  node = {
    'label': label,
    'type': type,
    'addr': addr,
    'children': {},
    'props': {},
    'name': build_node_name(name, addr)
  }
  while True:
    line = fd.readline()
    if not line:
      raise SyntaxError("parse_node: Missing } while parsing node")

    line = clean_line(line, fd)
    if not line:
      continue

    if line == "};":
      break

    if line.endswith('{'):
      new_node = parse_node(line, fd)
      node['children'][new_node['name']] = new_node
    else:
      key, value = parse_property(line, fd)
      node['props'][key] = value

  return node

def parse_file(fd, ignore_dts_version=False):
  nodes = {}
  has_v1_tag = False
  while True:
    line = fd.readline()
    if not line:
      break

    line = clean_line(line, fd)
    if not line:
      continue

    if line.startswith('/include/ '):
      tag, filename = line.split()
      with open(filename.strip()[1:-1], "r") as new_fd:
        nodes.update(parse_file(new_fd, True))
    elif line == '/dts-v1/;':
      has_v1_tag = True
    elif line.startswith('/memreserve/ ') and line.endswith(';'):
      tag, start, end = line.split()
      start = int(start, 16)
      end = int(end[:-1], 16)
      label = "reserved_memory_0x%x_0x%x" % (start, end)
      nodes[label] = {
        'type': 'memory',
        'reg': [start, end],
        'label': label,
        'addr': start,
        'name': build_node_name(name, start)
      }
    elif line.endswith('{'):
      if not has_v1_tag and not ignore_dts_version:
        raise SyntaxError("parse_file: Missing /dts-v1/ tag")

      new_node = parse_node(line, fd)
      nodes[new_node['name']] = new_node
    else:
      raise SyntaxError("parse_file: Couldn't understand the line: %s" % line)
  return nodes

def dump_refs(name, value, indent=0):
  spaces = '  ' * indent

  out = []
  if isinstance(value, dict) and 'ref' in value:
    out.append('%s\"%s\" -> \"%s\";' % (spaces, name, value['ref']))
  elif isinstance(value, list):
    for elem in value:
      out.extend(dump_refs(name, elem, indent))

  return out

def dump_all_refs(name, props, indent=0):
  out = []
  for key, value in props.items():
    out.extend(dump_refs(name, value, indent))
  return out

def next_subgraph(count=[0]):
  count[0] += 1
  return 'subgraph cluster_%d' % count[0]

def get_dot_node_name(node):
  name = node['name']
  return name[1:] if name[0] == '&' else name

def dump_to_dot(nodes, indent=0, start_string='digraph devicetree', name=None):
  spaces = '  ' * indent

  print("%s%s {" % (spaces, start_string))

  if name is not None:
    print("%slabel = \"%s\";" % (spaces, name))
    print("%s\"%s\";" % (spaces, name))

  ref_list = []
  for key, value in nodes.items():
    if value.get('children'):
      refs = dump_to_dot(value['children'], indent + 1, next_subgraph(), get_dot_node_name(value))
      ref_list.extend(refs)
    else:
      print("%s\"%s\";" % (spaces, get_dot_node_name(value)))

  for key, value in nodes.items():
    refs = dump_all_refs(get_dot_node_name(value), value.get('props', {}), indent)
    ref_list.extend(refs)

  if start_string.startswith("digraph"):
    print("%s%s" % (spaces, '\n'.join(ref_list)))

  print("%s}" % spaces)

  return ref_list

def main(args):
  if len(args) == 1:
    print('Usage: %s filename.dts' % args[0])
    return 1

  if '--dot' in args:
    formatter = dump_to_dot
    args.remove('--dot')
  else:
    formatter = lambda nodes: pprint.pprint(nodes, indent=2)

  with open(args[1], "r") as fd:
    formatter(parse_file(fd))

  return 0

if __name__ == '__main__':
  sys.exit(main(sys.argv))
