from __future__ import print_function
import sys
import os
import operator
from pycparser import c_parser, c_ast, parse_file
from math import *

from inspect import currentframe, getframeinfo
from collections import deque


def debug_print(frameinfo):
  print('******** ERROR:', frameinfo.filename, frameinfo.lineno, '********')


class StructItem():

  def __init__(self,
               typedef_name=None,
               struct_name=None,
               struct_node=None,
               is_union=False):
    self.typedef_name = typedef_name
    self.struct_name = struct_name
    self.struct_node = struct_node
    self.is_union = is_union
    self.child_decl_map = None

  def __str__(self):
    return str(self.typedef_name) + ' ' + str(self.struct_name) + ' ' + str(
        self.is_union)

  def compute_child_decl_map(self, struct_info):
    self.child_decl_map = {}
    if self.struct_node != None and self.struct_node.decls != None:
      for decl_node in self.struct_node.decls:
        if decl_node.name == None:
          for sub_decl_node in decl_node.type.decls:
            sub_decl_status = parse_decl_node(struct_info, sub_decl_node)
            self.child_decl_map[sub_decl_node.name] = sub_decl_status
        else:
          decl_status = parse_decl_node(struct_info, decl_node)
          self.child_decl_map[decl_status.name] = decl_status

  def get_child_decl_status(self, decl_name):
    if self.child_decl_map == None:
      debug_print(getframeinfo(currentframe()))
      print('child_decl_map is None')
      return None
    if decl_name not in self.child_decl_map:
      debug_print(getframeinfo(currentframe()))
      print(decl_name, 'does not exist ')
      return None
    return self.child_decl_map[decl_name]


class StructInfo():

  def __init__(self):
    self.struct_name_dic = {}
    self.typedef_name_dic = {}
    self.enum_value_dic = {}  # enum value -> enum_node
    self.enum_name_dic = {}  # enum name -> enum_node
    self.struct_item_list = []

  def get_struct_by_typedef_name(self, typedef_name):
    if typedef_name in self.typedef_name_dic:
      return self.typedef_name_dic[typedef_name]
    else:
      return None

  def get_struct_by_struct_name(self, struct_name):
    if struct_name in self.struct_name_dic:
      return self.struct_name_dic[struct_name]
    else:
      debug_print(getframeinfo(currentframe()))
      print('Cant find', struct_name)
      return None

  def update_struct_item_list(self):
    # Collect all struct_items from struct_name_dic and typedef_name_dic
    # Compute child_decl_map for each struct item.
    for struct_name in self.struct_name_dic.keys():
      struct_item = self.struct_name_dic[struct_name]
      struct_item.compute_child_decl_map(self)
      self.struct_item_list.append(struct_item)

    for typedef_name in self.typedef_name_dic.keys():
      struct_item = self.typedef_name_dic[typedef_name]
      if struct_item.struct_name not in self.struct_name_dic:
        struct_item.compute_child_decl_map(self)
        self.struct_item_list.append(struct_item)

  def update_enum(self, enum_node):
    if enum_node.name != None:
      self.enum_name_dic[enum_node.name] = enum_node

    if enum_node.values != None:
      enumerator_list = enum_node.values.enumerators
      for enumerator in enumerator_list:
        self.enum_value_dic[enumerator.name] = enum_node

  def update(self,
             typedef_name=None,
             struct_name=None,
             struct_node=None,
             is_union=False):
    """T: typedef_name S: struct_name N: struct_node

           T S N
   case 1: o o o
   typedef struct P {
    int u;
   } K;
           T S N
   case 2: o o x
   typedef struct P K;

           T S N
   case 3: x o o
   struct P {
    int u;
   };

           T S N
   case 4: o x o
   typedef struct {
    int u;
   } K;
    """
    struct_item = None

    # Check whether struct_name or typedef_name is already in the dictionary
    if struct_name in self.struct_name_dic:
      struct_item = self.struct_name_dic[struct_name]

    if typedef_name in self.typedef_name_dic:
      struct_item = self.typedef_name_dic[typedef_name]

    if struct_item == None:
      struct_item = StructItem(typedef_name, struct_name, struct_node, is_union)

    if struct_node.decls != None:
      struct_item.struct_node = struct_node

    if struct_name != None:
      self.struct_name_dic[struct_name] = struct_item

    if typedef_name != None:
      self.typedef_name_dic[typedef_name] = struct_item


class StructDefVisitor(c_ast.NodeVisitor):

  def __init__(self):
    self.struct_info = StructInfo()

  def visit_Struct(self, node):
    if node.decls != None:
      self.struct_info.update(None, node.name, node)
    self.generic_visit(node)

  def visit_Union(self, node):
    if node.decls != None:
      self.struct_info.update(None, node.name, node, True)
    self.generic_visit(node)

  def visit_Enum(self, node):
    self.struct_info.update_enum(node)
    self.generic_visit(node)

  def visit_Typedef(self, node):
    if node.type.__class__.__name__ == 'TypeDecl':
      typedecl = node.type
      if typedecl.type.__class__.__name__ == 'Struct':
        struct_node = typedecl.type
        typedef_name = node.name
        struct_name = struct_node.name
        self.struct_info.update(typedef_name, struct_name, struct_node)
      elif typedecl.type.__class__.__name__ == 'Union':
        union_node = typedecl.type
        typedef_name = node.name
        union_name = union_node.name
        self.struct_info.update(typedef_name, union_name, union_node, True)
      # TODO(angiebird): Do we need to deal with enum here?
    self.generic_visit(node)


def build_struct_info(ast):
  v = StructDefVisitor()
  v.visit(ast)
  struct_info = v.struct_info
  struct_info.update_struct_item_list()
  return v.struct_info


class DeclStatus():

  def __init__(self, name, struct_item=None, is_ptr_decl=False):
    self.name = name
    self.struct_item = struct_item
    self.is_ptr_decl = is_ptr_decl

  def get_child_decl_status(self, decl_name):
    if self.struct_item != None:
      return self.struct_item.get_child_decl_status(decl_name)
    else:
      #TODO(angiebird): 2. Investigage the situation when a struct's definition can't be found.
      return None

  def __str__(self):
    return str(self.struct_item) + ' ' + str(self.name) + ' ' + str(
        self.is_ptr_decl)


def peel_ptr_decl(decl_type_node):
  """ Remove PtrDecl and ArrayDecl layer """
  is_ptr_decl = False
  peeled_decl_type_node = decl_type_node
  while peeled_decl_type_node.__class__.__name__ == 'PtrDecl' or peeled_decl_type_node.__class__.__name__ == 'ArrayDecl':
    is_ptr_decl = True
    peeled_decl_type_node = peeled_decl_type_node.type
  return is_ptr_decl, peeled_decl_type_node


def parse_peeled_decl_type_node(struct_info, node):
  struct_item = None
  if node.__class__.__name__ == 'TypeDecl':
    if node.type.__class__.__name__ == 'IdentifierType':
      identifier_type_node = node.type
      typedef_name = identifier_type_node.names[0]
      struct_item = struct_info.get_struct_by_typedef_name(typedef_name)
    elif node.type.__class__.__name__ == 'Struct':
      struct_node = node.type
      if struct_node.name != None:
        struct_item = struct_info.get_struct_by_struct_name(struct_node.name)
      else:
        struct_item = StructItem(None, None, struct_node, False)
        struct_item.compute_child_decl_map(struct_info)
    elif node.type.__class__.__name__ == 'Union':
      # TODO(angiebird): Special treatment for Union?
      struct_node = node.type
      if struct_node.name != None:
        struct_item = struct_info.get_struct_by_struct_name(struct_node.name)
      else:
        struct_item = StructItem(None, None, struct_node, True)
        struct_item.compute_child_decl_map(struct_info)
    elif node.type.__class__.__name__ == 'Enum':
      # TODO(angiebird): Special treatment for Union?
      struct_node = node.type
      struct_item = None
    else:
      print('Unrecognized peeled_decl_type_node.type',
            node.type.__class__.__name__)
  else:
    # debug_print(getframeinfo(currentframe()))
    # print(node.__class__.__name__)
    #TODO(angiebird): Do we need to take care of this part?
    pass

  return struct_item


def parse_decl_node(struct_info, decl_node):
  # struct_item is None if this decl_node is not a struct_item
  decl_node_name = decl_node.name
  decl_type_node = decl_node.type
  is_ptr_decl, peeled_decl_type_node = peel_ptr_decl(decl_type_node)
  struct_item = parse_peeled_decl_type_node(struct_info, peeled_decl_type_node)
  return DeclStatus(decl_node_name, struct_item, is_ptr_decl)


def get_lvalue_lead(lvalue_node):
  """return '&' or '*' of lvalue if available"""
  if lvalue_node.__class__.__name__ == 'UnaryOp' and lvalue_node.op == '&':
    return '&'
  elif lvalue_node.__class__.__name__ == 'UnaryOp' and lvalue_node.op == '*':
    return '*'
  return None


def parse_lvalue(lvalue_node):
  """get id_chain from lvalue"""
  id_chain = parse_lvalue_recursive(lvalue_node, [])
  return id_chain


def parse_lvalue_recursive(lvalue_node, id_chain):
  """cpi->rd->u -> (cpi->rd)->u"""
  if lvalue_node.__class__.__name__ == 'ID':
    id_chain.append(lvalue_node.name)
    id_chain.reverse()
    return id_chain
  elif lvalue_node.__class__.__name__ == 'StructRef':
    id_chain.append(lvalue_node.field.name)
    return parse_lvalue_recursive(lvalue_node.name, id_chain)
  elif lvalue_node.__class__.__name__ == 'ArrayRef':
    return parse_lvalue_recursive(lvalue_node.name, id_chain)
  elif lvalue_node.__class__.__name__ == 'UnaryOp' and lvalue_node.op == '&':
    return parse_lvalue_recursive(lvalue_node.expr, id_chain)
  elif lvalue_node.__class__.__name__ == 'UnaryOp' and lvalue_node.op == '*':
    return parse_lvalue_recursive(lvalue_node.expr, id_chain)
  else:
    return None


class FuncDefVisitor(c_ast.NodeVisitor):
  func_dictionary = {}

  def visit_FuncDef(self, node):
    func_name = node.decl.name
    self.func_dictionary[func_name] = node


def build_func_dictionary(ast):
  v = FuncDefVisitor()
  v.visit(ast)
  return v.func_dictionary


def get_func_start_coord(func_node):
  return func_node.coord


def find_end_node(node):
  node_list = []
  for c in node:
    node_list.append(c)
  if len(node_list) == 0:
    return node
  else:
    return find_end_node(node_list[-1])


def get_func_end_coord(func_node):
  return find_end_node(func_node).coord


def get_func_size(func_node):
  start_coord = get_func_start_coord(func_node)
  end_coord = get_func_end_coord(func_node)
  if start_coord.file == end_coord.file:
    return end_coord.line - start_coord.line + 1
  else:
    return None


def save_object(obj, filename):
  with open(filename, 'wb') as obj_fp:
    pickle.dump(obj, obj_fp, protocol=-1)


def load_object(filename):
  obj = None
  with open(filename, 'rb') as obj_fp:
    obj = pickle.load(obj_fp)
  return obj


def get_av1_ast(gen_ast=False):
  # TODO(angiebird): Generalize this path
  c_filename = './av1_pp.c'
  print('generate ast')
  ast = parse_file(c_filename)
  #save_object(ast, ast_file)
  print('finished generate ast')
  return ast


def get_func_param_id_map(func_def_node):
  param_id_map = {}
  func_decl = func_def_node.decl.type
  param_list = func_decl.args.params
  for decl in param_list:
    param_id_map[decl.name] = decl
  return param_id_map


class IDTreeStack():

  def __init__(self, global_id_tree):
    self.stack = deque()
    self.global_id_tree = global_id_tree

  def add_link_node(self, node, link_id_chain):
    link_node = self.add_id_node(link_id_chain)
    node.link_node = link_node
    node.link_id_chain = link_id_chain

  def push_id_tree(self, id_tree=None):
    if id_tree == None:
      id_tree = IDStatusNode()
    self.stack.append(id_tree)
    return id_tree

  def pop_id_tree(self):
    return self.stack.pop()

  def add_id_seed_node(self, id_seed, decl_status):
    return self.stack[-1].add_child(id_seed, decl_status)

  def get_id_seed_node(self, id_seed):
    idx = len(self.stack) - 1
    while idx >= 0:
      id_node = self.stack[idx].get_child(id_seed)
      if id_node != None:
        return id_node
      idx -= 1

    id_node = self.global_id_tree.get_child(id_seed)
    if id_node != None:
      return id_node
    return None

  def add_id_node(self, id_chain):
    id_seed = id_chain[0]
    id_seed_node = self.get_id_seed_node(id_seed)
    if id_seed_node == None:
      return None
    if len(id_chain) == 1:
      return id_seed_node
    return id_seed_node.add_descendant(id_chain[1:])

  def get_id_node(self, id_chain):
    id_seed = id_chain[0]
    id_seed_node = self.get_id_seed_node(id_seed)
    if id_seed_node == None:
      return None
    if len(id_chain) == 1:
      return id_seed_node
    return id_seed_node.get_descendant(id_chain[1:])

  def top(self):
    return self.stack[-1]


class IDStatusNode():

  def __init__(self, name=None, root=None):
    if root is None:
      self.root = self
    else:
      self.root = root

    self.name = name

    self.parent = None
    self.children = {}

    self.assign = False
    self.refer = False

    self.decl_status = None

    self.link_id_chain = None
    self.link_node = None

    self.visit = False

  def set_link_id_chain(self, link_id_chain):
    self.set_assign(False)
    self.link_id_chain = link_id_chain
    self.link_node = self.root.get_descendant(link_id_chain)

  def set_link_node(self, link_node):
    self.set_assign(False)
    self.link_id_chain = ['*']
    self.link_node = link_node

  def get_link_id_chain(self):
    return self.link_id_chain

  def get_concrete_node(self):
    if self.visit == True:
      # return None when there is a loop
      return None
    self.visit = True
    if self.link_node == None:
      self.visit = False
      return self
    else:
      concrete_node = self.link_node.get_concrete_node()
      self.visit = False
      if concrete_node == None:
        return self
      return concrete_node

  def set_assign(self, assign):
    concrete_node = self.get_concrete_node()
    concrete_node.assign = assign

  def get_assign(self):
    concrete_node = self.get_concrete_node()
    return concrete_node.assign

  def set_refer(self, refer):
    concrete_node = self.get_concrete_node()
    concrete_node.refer = refer

  def get_refer(self):
    concrete_node = self.get_concrete_node()
    return concrete_node.refer

  def set_parent(self, parent):
    concrete_node = self.get_concrete_node()
    concrete_node.parent = parent

  def add_child(self, name, decl_status=None):
    concrete_node = self.get_concrete_node()
    if name not in concrete_node.children:
      child_id_node = IDStatusNode(name, concrete_node.root)
      concrete_node.children[name] = child_id_node
      if decl_status == None:
        # Check if the child decl_status can be inferred from its parent's
        # decl_status
        if self.decl_status != None:
          decl_status = self.decl_status.get_child_decl_status(name)
      child_id_node.set_decl_status(decl_status)
    return concrete_node.children[name]

  def get_child(self, name):
    concrete_node = self.get_concrete_node()
    if name in concrete_node.children:
      return concrete_node.children[name]
    else:
      return None

  def add_descendant(self, id_chain):
    current_node = self.get_concrete_node()
    for name in id_chain:
      current_node.add_child(name)
      parent_node = current_node
      current_node = current_node.get_child(name)
      current_node.set_parent(parent_node)
    return current_node

  def get_descendant(self, id_chain):
    current_node = self.get_concrete_node()
    for name in id_chain:
      current_node = current_node.get_child(name)
      if current_node == None:
        return None
    return current_node

  def get_children(self):
    current_node = self.get_concrete_node()
    return current_node.children

  def set_decl_status(self, decl_status):
    current_node = self.get_concrete_node()
    current_node.decl_status = decl_status

  def get_decl_status(self):
    current_node = self.get_concrete_node()
    return current_node.decl_status

  def __str__(self):
    if self.link_id_chain is None:
      return str(self.name) + ' a: ' + str(int(self.assign)) + ' r: ' + str(
          int(self.refer))
    else:
      return str(self.name) + ' -> ' + ' '.join(self.link_id_chain)

  def show(self, id_chain=None):
    if id_chain == None:
      id_chain = []
    id_chain.append(self.name)
    if self.assign or self.refer:
      print(' '.join(id_chain[1:]), 'a:', int(self.assign), 'r:',
            int(self.refer))
    for c in self.children:
      self.children[c].show(id_chain)
    id_chain.pop()


class FuncInOutVisitor(c_ast.NodeVisitor):

  def __init__(self,
               func_def_node,
               struct_info,
               func_dictionary,
               keep_body_id_tree=True,
               call_param_map=None,
               global_id_tree=None,
               func_history=None,
               unknown=None):
    self.func_dictionary = func_dictionary
    self.struct_info = struct_info
    self.param_id_map = get_func_param_id_map(func_def_node)
    self.parent_node = None
    self.global_id_tree = global_id_tree
    self.body_id_tree = None
    self.keep_body_id_tree = keep_body_id_tree
    if func_history == None:
      self.func_history = {}
    else:
      self.func_history = func_history

    if unknown == None:
      self.unknown = []
    else:
      self.unknown = unknown

    self.id_tree_stack = IDTreeStack(global_id_tree)
    self.id_tree_stack.push_id_tree()

    #TODO move this part into a function
    for param in self.param_id_map:
      decl_node = self.param_id_map[param]
      decl_status = parse_decl_node(self.struct_info, decl_node)
      descendant = self.id_tree_stack.add_id_seed_node(decl_status.name,
                                                       decl_status)
      if call_param_map is not None and param in call_param_map:
        # This is a function call.
        # Map the input parameter to the caller's nodes
        # TODO(angiebird): Can we use add_link_node here?
        descendant.set_link_node(call_param_map[param])

  def get_id_tree_stack(self):
    return self.id_tree_stack

  def generic_visit(self, node):
    prev_parent = self.parent_node
    self.parent_node = node
    for c in node:
      self.visit(c)
    self.parent_node = prev_parent

  # TODO rename
  def add_new_id_tree(self, node):
    self.id_tree_stack.push_id_tree()
    self.generic_visit(node)
    id_tree = self.id_tree_stack.pop_id_tree()
    if self.parent_node == None and self.keep_body_id_tree == True:
      # this is function body
      self.body_id_tree = id_tree

  def visit_For(self, node):
    self.add_new_id_tree(node)

  def visit_Compound(self, node):
    self.add_new_id_tree(node)

  def visit_Decl(self, node):
    if node.type.__class__.__name__ != 'FuncDecl':
      decl_status = parse_decl_node(self.struct_info, node)
      descendant = self.id_tree_stack.add_id_seed_node(decl_status.name,
                                                       decl_status)
      if node.init is not None:
        init_id_chain = self.process_lvalue(node.init)
        if init_id_chain != None:
          if decl_status.struct_item is None:
            init_descendant = self.id_tree_stack.add_id_node(init_id_chain)
            if init_descendant != None:
              init_descendant.set_refer(True)
            else:
              self.unknown.append(node)
            descendant.set_assign(True)
          else:
            self.id_tree_stack.add_link_node(descendant, init_id_chain)
        else:
          self.unknown.append(node)
      else:
        descendant.set_assign(True)
      self.generic_visit(node)

  def is_lvalue(self, node):
    if self.parent_node is None:
      # TODO(angiebird): Do every lvalue has parent_node != None?
      return False
    if self.parent_node.__class__.__name__ == 'StructRef':
      return False
    if self.parent_node.__class__.__name__ == 'ArrayRef' and node == self.parent_node.name:
      # if node == self.parent_node.subscript, the node could be lvalue
      return False
    if self.parent_node.__class__.__name__ == 'UnaryOp' and self.parent_node.op == '&':
      return False
    if self.parent_node.__class__.__name__ == 'UnaryOp' and self.parent_node.op == '*':
      return False
    return True

  def process_lvalue(self, node):
    id_chain = parse_lvalue(node)
    if id_chain == None:
      return id_chain
    elif id_chain[0] in self.struct_info.enum_value_dic:
      return None
    else:
      return id_chain

  def process_possible_lvalue(self, node):
    if self.is_lvalue(node):
      id_chain = self.process_lvalue(node)
      lead_char = get_lvalue_lead(node)
      # make sure the id is not an enum value
      if id_chain == None:
        self.unknown.append(node)
        return
      descendant = self.id_tree_stack.add_id_node(id_chain)
      if descendant == None:
        self.unknown.append(node)
        return
      decl_status = descendant.get_decl_status()
      if decl_status == None:
        descendant.set_assign(True)
        descendant.set_refer(True)
        self.unknown.append(node)
        return
      if self.parent_node.__class__.__name__ == 'Assignment':
        if node is self.parent_node.lvalue:
          if decl_status.struct_item != None:
            if len(id_chain) > 1:
              descendant.set_assign(True)
            elif len(id_chain) == 1:
              if lead_char == '*':
                descendant.set_assign(True)
              else:
                right_id_chain = self.process_lvalue(self.parent_node.rvalue)
                if right_id_chain != None:
                  self.id_tree_stack.add_link_node(descendant, right_id_chain)
                else:
                  #TODO(angiebird): 1.Find a better way to deal with this case.
                  descendant.set_assign(True)
            else:
              debug_print(getframeinfo(currentframe()))
          else:
            descendant.set_assign(True)
        elif node is self.parent_node.rvalue:
          if decl_status.struct_item is None:
            descendant.set_refer(True)
            if lead_char == '&':
              descendant.set_assign(True)
          else:
            left_id_chain = self.process_lvalue(self.parent_node.lvalue)
            left_lead_char = get_lvalue_lead(self.parent_node.lvalue)
            if left_id_chain != None:
              if len(left_id_chain) > 1:
                descendant.set_refer(True)
              elif len(left_id_chain) == 1:
                if left_lead_char == '*':
                  descendant.set_refer(True)
                else:
                  #TODO(angiebird): Check whether the other node is linked to this node.
                  pass
              else:
                self.unknown.append(self.parent_node.lvalue)
                debug_print(getframeinfo(currentframe()))
            else:
              self.unknown.append(self.parent_node.lvalue)
              debug_print(getframeinfo(currentframe()))
        else:
          debug_print(getframeinfo(currentframe()))
      elif self.parent_node.__class__.__name__ == 'UnaryOp':
        # TODO(angiebird): Consider +=, *=, -=, /= etc
        if self.parent_node.op == '--' or self.parent_node.op == '++' or\
        self.parent_node.op == 'p--' or self.parent_node.op == 'p++':
          descendant.set_assign(True)
          descendant.set_refer(True)
        else:
          descendant.set_refer(True)
      elif self.parent_node.__class__.__name__ == 'Decl':
        #The logic is at visit_Decl
        pass
      elif self.parent_node.__class__.__name__ == 'ExprList':
        #The logic is at visit_FuncCall
        pass
      else:
        descendant.set_refer(True)

  def visit_ID(self, node):
    # If the parent is a FuncCall, this ID is a function name.
    if self.parent_node.__class__.__name__ != 'FuncCall':
      self.process_possible_lvalue(node)
    self.generic_visit(node)

  def visit_StructRef(self, node):
    self.process_possible_lvalue(node)
    self.generic_visit(node)

  def visit_ArrayRef(self, node):
    self.process_possible_lvalue(node)
    self.generic_visit(node)

  def visit_UnaryOp(self, node):
    if node.op == '&' or node.op == '*':
      self.process_possible_lvalue(node)
    self.generic_visit(node)

  def visit_FuncCall(self, node):
    if node.name.__class__.__name__ == 'ID':
      if node.name.name in self.func_dictionary:
        if node.name.name not in self.func_history:
          self.func_history[node.name.name] = True
          func_def_node = self.func_dictionary[node.name.name]
          call_param_map = self.process_func_call(node, func_def_node)

          visitor = FuncInOutVisitor(func_def_node, self.struct_info,
                                     self.func_dictionary, False,
                                     call_param_map, self.global_id_tree,
                                     self.func_history, self.unknown)
          visitor.visit(func_def_node.body)
    else:
      self.unknown.append(node)
    self.generic_visit(node)

  def process_func_call(self, func_call_node, func_def_node):
    # set up a refer/assign for func parameters
    # return call_param_map
    call_param_ls = func_call_node.args.exprs
    call_param_map = {}

    func_decl = func_def_node.decl.type
    decl_param_ls = func_decl.args.params
    for param_node, decl_node in zip(call_param_ls, decl_param_ls):
      id_chain = self.process_lvalue(param_node)
      if id_chain != None:
        descendant = self.id_tree_stack.add_id_node(id_chain)
        if descendant == None:
          self.unknown.append(param_node)
        else:
          decl_status = descendant.get_decl_status()
          if decl_status != None:
            if decl_status.struct_item == None:
              if decl_status.is_ptr_decl == True:
                descendant.set_assign(True)
                descendant.set_refer(True)
              else:
                descendant.set_refer(True)
            else:
              call_param_map[decl_node.name] = descendant
          else:
            self.unknown.append(param_node)
      else:
        self.unknown.append(param_node)
    return call_param_map


def build_global_id_tree(ast, struct_info):
  global_id_tree = IDStatusNode()
  for node in ast.ext:
    if node.__class__.__name__ == 'Decl':
      # id tree is for tracking assign/refer status
      # we don't care about function id because they can't be changed
      if node.type.__class__.__name__ != 'FuncDecl':
        decl_status = parse_decl_node(struct_info, node)
        descendant = global_id_tree.add_child(decl_status.name, decl_status)
  return global_id_tree


class FuncAnalyzer():

  def __init__(self):
    self.ast = get_av1_ast()
    self.struct_info = build_struct_info(self.ast)
    self.func_dictionary = build_func_dictionary(self.ast)
    self.global_id_tree = build_global_id_tree(self.ast, self.struct_info)

  def analyze(self, func_name):
    if func_name in self.func_dictionary:
      func_def_node = self.func_dictionary[func_name]
      visitor = FuncInOutVisitor(func_def_node, self.struct_info,
                                 self.func_dictionary, True, None,
                                 self.global_id_tree)
      visitor.visit(func_def_node.body)
      root = visitor.get_id_tree_stack()
      root.top().show()
    else:
      print(func_name, "doesn't exist")


if __name__ == '__main__':
  fa = FuncAnalyzer()
  fa.analyze('tpl_get_satd_cost')
  pass
