#!/usr/bin/env python3
#
# 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, None

  return label, name.strip(), addr, 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
  elif isinstance(addr, int):
    return '%s@%x' % (name, addr)

  return '%s@%s' % (name, addr.strip())

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

  node = {
    'label': label,
    'type': type,
    'addr': numeric_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))
