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.last_assign_coord = None
    self.refer = False
    self.last_refer_coord = None

    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, coord=None):
    concrete_node = self.get_concrete_node()
    concrete_node.assign = assign
    concrete_node.last_assign_coord = coord

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

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

  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 collect_assign_refer_status(self,
                                  id_chain=None,
                                  assign_ls=None,
                                  refer_ls=None):
    if id_chain == None:
      id_chain = []
    if assign_ls == None:
      assign_ls = []
    if refer_ls == None:
      refer_ls = []
    id_chain.append(self.name)
    if self.assign:
      info_str = ' '.join([
          ' '.join(id_chain[1:]), 'a:',
          str(int(self.assign)), 'r:',
          str(int(self.refer)),
          str(self.last_assign_coord)
      ])
      assign_ls.append(info_str)
    if self.refer:
      info_str = ' '.join([
          ' '.join(id_chain[1:]), 'a:',
          str(int(self.assign)), 'r:',
          str(int(self.refer)),
          str(self.last_refer_coord)
      ])
      refer_ls.append(info_str)
    for c in self.children:
      self.children[c].collect_assign_refer_status(id_chain, assign_ls,
                                                   refer_ls)
    id_chain.pop()
    return assign_ls, refer_ls

  def show(self):
    assign_ls, refer_ls = self.collect_assign_refer_status()
    print('---- assign ----')
    for item in assign_ls:
      print(item)
    print('---- refer ----')
    for item in refer_ls:
      print(item)


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, node.coord)
            else:
              self.unknown.append(node)
            descendant.set_assign(True, node.coord)
          else:
            self.id_tree_stack.add_link_node(descendant, init_id_chain)
        else:
          self.unknown.append(node)
      else:
        descendant.set_assign(True, node.coord)
      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, node.coord)
        descendant.set_refer(True, node.coord)
        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, node.coord)
            elif len(id_chain) == 1:
              if lead_char == '*':
                descendant.set_assign(True, node.coord)
              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, node.coord)
            else:
              debug_print(getframeinfo(currentframe()))
          else:
            descendant.set_assign(True, node.coord)
        elif node is self.parent_node.rvalue:
          if decl_status.struct_item is None:
            descendant.set_refer(True, node.coord)
            if lead_char == '&':
              descendant.set_assign(True, node.coord)
          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, node.coord)
              elif len(left_id_chain) == 1:
                if left_lead_char == '*':
                  descendant.set_refer(True, node.coord)
                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, node.coord)
          descendant.set_refer(True, node.coord)
        else:
          descendant.set_refer(True, node.coord)
      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, node.coord)

  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, param_node.coord)
                descendant.set_refer(True, param_node.coord)
              else:
                descendant.set_refer(True, param_node.coord)
            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
