# Copyright (c) 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


class FileDictionary(object):
  """Maps file in a stacktrace to its crash information.

  It maps file to another dictionary, which maps the file's path to crashed
  lines, stack frame indices and crashed functions.
  """

  def __init__(self):
    """Initializes the file dictionary."""
    self.file_dict = {}

  def AddFile(self, file_path, crashed_line_range, stack_frame_index,
              function):
    """Adds file and its crash information to the map.

    Args:
      file_path: The path of the crashed file.
      crashed_line_range: The crashed line of the file.
      stack_frame_index: The file's position in the callstack.
      function: The name of the crashed function.
    """
    # Populate the dictionary if this file path has not been added before.
    if file_path not in self.file_dict:
      self.file_dict[file_path] = {}
      self.file_dict[file_path]['line_numbers'] = []
      self.file_dict[file_path]['stack_frame_indices'] = []
      self.file_dict[file_path]['function'] = []

    # Add the crashed line, frame index and function name.
    self.file_dict[file_path]['line_numbers'].append(
        crashed_line_range)
    self.file_dict[file_path]['stack_frame_indices'].append(
        stack_frame_index)
    self.file_dict[file_path]['function'].append(function)

  def GetCrashedLineNumbers(self, file_path):
    """Returns crashed line numbers given a file path."""
    return self.file_dict[file_path]['line_numbers']

  def GetCrashStackFrameIndices(self, file_path):
    """Returns stack frame indices given a file path."""
    return self.file_dict[file_path]['stack_frame_indices']

  def GetCrashFunctions(self, file_path):
    """Returns list of crashed functions given a file path."""
    return self.file_dict[file_path]['function']

  def __iter__(self):
    return iter(self.file_dict)


class ComponentDictionary(object):
  """Represents a file dictionary.

  It maps each component path to a file dictionary.
  """

  def __init__(self, callstack, components):
    """Initializes the dictionary with given components."""
    self.component_dict = {}

    # Create file dictionary for all the components.
    for component in components:
      self.component_dict[component] = FileDictionary()

    # Create file dict from callstack.
    self.__CreateFileDictFromCallstack(callstack)

  def GetFileDict(self, component):
    """Returns a file dictionary for a given component."""
    return self.component_dict.get(component)

  def __GenerateFileDict(self, stack_frame_list):
    """Generates file dictionary, given an instance of StackFrame list."""
    # Iterate through the list of stackframe objects.
    for stack_frame in stack_frame_list:
      # If the component of this line is not in the list of components to
      # look for, ignore this line.
      component_path = stack_frame.component_path
      if component_path not in self.component_dict:
        continue

      # Get values of the variables
      file_path = stack_frame.file_path
      crashed_line_range = stack_frame.crashed_line_range
      stack_frame_index = stack_frame.index
      function = stack_frame.function

      # Add the file to this component's dictionary of files.
      file_dict = self.component_dict[component_path]
      file_dict.AddFile(file_path, crashed_line_range, stack_frame_index,
                        function)

  def __CreateFileDictFromCallstack(self, callstack, top_n_frames=10):
    """Creates a file dict that maps a file to the occurrence in the stack.

    Args:
      callstack: A list containing parsed result from a single stack
                  within a stacktrace. For example, a stacktrace from
                  previously-allocated thread in release build stacktrace.
      top_n_frames: The number of frames to look for.

    Returns:
      Component_dict, a dictionary with key as a file name and value as another
      dictionary, which maps the file's path (because there can be multiple
      files with same name but in different directory) to the list of this
      file's place in stack, lines that this file caused a crash, and the name
      of the function.
    """

    # Only look at first top_n_frames of the stacktrace, below those are likely
    # to be noisy. Parse the stacktrace into the component dictionary.
    stack_list = callstack.GetTopNFrames(top_n_frames)
    self.__GenerateFileDict(stack_list)

  def __iter__(self):
    return iter(self.component_dict)
