# Copyright 2017 Google Inc.
#
# 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 logging

from collections import defaultdict
from enum import Enum
from mobly import base_test
from mobly import records
from mobly import signals
from mobly import utils


class _InstrumentationStructurePrefixes:
  """Class containing prefixes that structure insturmentation output.

  Android instrumentation generally follows the following format:

  .. code-block:: none

    INSTRUMENTATION_STATUS: ...
    ...
    INSTRUMENTATION_STATUS: ...
    INSTRUMENTATION_STATUS_CODE: ...
    INSTRUMENTATION_STATUS: ...
    ...
    INSTRUMENTATION_STATUS: ...
    INSTRUMENTATION_STATUS_CODE: ...
    ...
    INSTRUMENTATION_RESULT: ...
    ...
    INSTRUMENTATION_RESULT: ...
    ...
    INSTRUMENTATION_CODE: ...

  This means that these prefixes can be used to guide parsing
  the output of the instrumentation command into the different
  instrumetnation test methods.

  Refer to the following Android Framework package for more details:

  .. code-block:: none

    com.android.commands.am.AM

  """

  STATUS = 'INSTRUMENTATION_STATUS:'
  STATUS_CODE = 'INSTRUMENTATION_STATUS_CODE:'
  RESULT = 'INSTRUMENTATION_RESULT:'
  CODE = 'INSTRUMENTATION_CODE:'
  FAILED = 'INSTRUMENTATION_FAILED:'


class _InstrumentationKnownStatusKeys:
  """Commonly used keys used in instrumentation output for listing
  instrumentation test method result properties.

  An instrumenation status line usually contains a key-value pair such as
  the following:

  .. code-block:: none

    INSTRUMENTATION_STATUS: <key>=<value>

  Some of these key-value pairs are very common and represent test case
  properties. This mapping is used to handle each of the corresponding
  key-value pairs different than less important key-value pairs.

  Refer to the following Android Framework packages for more details:

  .. code-block:: none

    android.app.Instrumentation
    android.support.test.internal.runner.listener.InstrumentationResultPrinter

  TODO: Convert android.support.* to androidx.*,
  (https://android-developers.googleblog.com/2018/05/hello-world-androidx.html).
  """

  CLASS = 'class'
  ERROR = 'Error'
  STACK = 'stack'
  TEST = 'test'
  STREAM = 'stream'


class _InstrumentationStatusCodes:
  """A mapping of instrumentation status codes to test method results.

  When instrumentation runs, at various points output is created in a series
  of blocks that terminate as follows:

  .. code-block:: none

    INSTRUMENTATION_STATUS_CODE: 1

  These blocks typically have several status keys in them, and they indicate
  the progression of a particular instrumentation test method. When the
  corresponding instrumentation test method finishes, there is generally a
  line which includes a status code that gives thes the test result.

  The UNKNOWN status code is not an actual status code and is only used to
  represent that a status code has not yet been read for an instrumentation
  block.

  Refer to the following Android Framework package for more details:

  .. code-block:: none

    android.support.test.internal.runner.listener.InstrumentationResultPrinter

  TODO: Convert android.support.* to androidx.*,
  (https://android-developers.googleblog.com/2018/05/hello-world-androidx.html).
  """

  UNKNOWN = None
  OK = '0'
  START = '1'
  IN_PROGRESS = '2'
  ERROR = '-1'
  FAILURE = '-2'
  IGNORED = '-3'
  ASSUMPTION_FAILURE = '-4'


class _InstrumentationStatusCodeCategories:
  """A mapping of instrumentation test method results to categories.

  Aside from the TIMING category, these categories roughly map to Mobly
  signals and are used for determining how a particular instrumentation test
  method gets recorded.
  """

  TIMING = [
      _InstrumentationStatusCodes.START,
      _InstrumentationStatusCodes.IN_PROGRESS,
  ]
  PASS = [
      _InstrumentationStatusCodes.OK,
  ]
  FAIL = [
      _InstrumentationStatusCodes.ERROR,
      _InstrumentationStatusCodes.FAILURE,
  ]
  SKIPPED = [
      _InstrumentationStatusCodes.IGNORED,
      _InstrumentationStatusCodes.ASSUMPTION_FAILURE,
  ]


class _InstrumentationKnownResultKeys:
  """Commonly used keys for outputting instrumentation errors.

  When instrumentation finishes running all of the instrumentation test
  methods, a result line will appear as follows:

  .. code-block:: none

    INSTRUMENTATION_RESULT:

  If something wrong happened during the instrumentation run such as an
  application under test crash, the line will appear similarly as thus:

  .. code-block:: none

    INSTRUMENTATION_RESULT: shortMsg=Process crashed.

  Since these keys indicate that something wrong has happened to the
  instrumentation run, they should be checked for explicitly.

  Refer to the following documentation page for more information:

  .. code-block:: none

    https://developer.android.com/reference/android/app/ActivityManager.ProcessErrorStateInfo.html

  """

  LONGMSG = 'longMsg'
  SHORTMSG = 'shortMsg'


class _InstrumentationResultSignals:
  """Instrumenttion result block strings for signalling run completion.

  The final section of the instrumentation output generally follows this
  format:

  .. code-block:: none

    INSTRUMENTATION_RESULT: stream=
    ...
    INSTRUMENTATION_CODE -1

  Inside of the ellipsed section, one of these signaling strings should be
  present. If they are not present, this usually means that the
  instrumentation run has failed in someway such as a crash. Because the
  final instrumentation block simply summarizes information, simply roughly
  checking for a particilar string should be sufficient to check to a proper
  run completion as the contents of the instrumentation result block don't
  really matter.

  Refer to the following JUnit package for more details:

  .. code-block:: none

    junit.textui.ResultPrinter

  """

  FAIL = 'FAILURES!!!'
  PASS = 'OK ('


class _InstrumentationBlockStates(Enum):
  """States used for determing what the parser is currently parsing.

  The parse always starts and ends a block in the UNKNOWN state, which is
  used to indicate that either a method or a result block (matching the
  METHOD and RESULT states respectively) are valid follow ups, which means
  that parser should be checking for a structure prefix that indicates which
  of those two states it should transition to. If the parser is in the
  METHOD state, then the parser will be parsing input into test methods.
  Otherwise, the parse can simply concatenate all the input to check for
  some final run completion signals.
  """

  UNKNOWN = 0
  METHOD = 1
  RESULT = 2


class _InstrumentationBlock:
  """Container class for parsed instrumentation output for instrumentation
  test methods.

  Instrumentation test methods typically follow the follwoing format:

  .. code-block:: none

    INSTRUMENTATION_STATUS: <key>=<value>
    ...
    INSTRUMENTATION_STATUS: <key>=<value>
    INSTRUMENTATION_STATUS_CODE: <status code #>

  The main issue with parsing this however is that the key-value pairs can
  span multiple lines such as this:

  .. code-block:: none

    INSTRUMENTATION_STATUS: stream=
    Error in ...
    ...

  Or, such as this:

  .. code-block:: none

    INSTRUMENTATION_STATUS: stack=...
    ...

  Because these keys are poentially very long, constant string contatention
  is potentially inefficent. Instead, this class builds up a buffer to store
  the raw output until it is processed into an actual test result by the
  _InstrumentationBlockFormatter class.

  Additionally, this class also serves to store the parser state, which
  means that the BaseInstrumentationTestClass does not need to keep any
  potentially volatile instrumentation related state, so multiple
  instrumentation runs should have completely separate parsing states.

  This class is also used for storing result blocks although very little
  needs to be done for those.

  Attributes:
    begin_time: string, optional timestamp for when the test corresponding
      to the instrumentation block began.
    current_key: string, the current key that is being parsed, default to
      _InstrumentationKnownStatusKeys.STREAM.
    error_message: string, an error message indicating that something
      unexpected happened during a instrumentatoin test method.
    known_keys: dict, well known keys that are handled uniquely.
    prefix: string, a prefix to add to the class name of the
      instrumentation test methods.
    previous_instrumentation_block: _InstrumentationBlock, the last parsed
      instrumentation block.
    state: _InstrumentationBlockStates, the current state of the parser.
    status_code: string, the state code for an instrumentation method
      block.
    unknown_keys: dict, arbitrary keys that are handled generically.
  """

  def __init__(self,
               state=_InstrumentationBlockStates.UNKNOWN,
               prefix=None,
               previous_instrumentation_block=None):
    self.state = state
    self.prefix = prefix
    self.previous_instrumentation_block = previous_instrumentation_block
    if previous_instrumentation_block:
      # The parser never needs lookback for two previous blocks,
      # so unset to allow previous blocks to get garbage collected.
      previous_instrumentation_block.previous_instrumentation_block = None

    self._empty = True
    self.error_message = ''
    self.status_code = _InstrumentationStatusCodes.UNKNOWN

    self.current_key = _InstrumentationKnownStatusKeys.STREAM
    self.known_keys = {
        _InstrumentationKnownStatusKeys.STREAM: [],
        _InstrumentationKnownStatusKeys.CLASS: [],
        _InstrumentationKnownStatusKeys.ERROR: [],
        _InstrumentationKnownStatusKeys.STACK: [],
        _InstrumentationKnownStatusKeys.TEST: [],
        _InstrumentationKnownResultKeys.LONGMSG: [],
        _InstrumentationKnownResultKeys.SHORTMSG: [],
    }
    self.unknown_keys = defaultdict(list)

    self.begin_time = None

  @property
  def is_empty(self):
    """Deteremines whether or not anything has been parsed with this
    instrumentation block.

    Returns:
      A boolean indicating whether or not the this instrumentation block
      has parsed and contains any output.
    """
    return self._empty

  def set_error_message(self, error_message):
    """Sets an error message on an instrumentation block.

    This method is used exclusively to indicate that a test method failed
    to complete, which is usually cause by a crash of some sort such that
    the test method is marked as error instead of ignored.

    Args:
      error_message: string, an error message to be added to the
        TestResultRecord to explain that something wrong happened.
    """
    self._empty = False
    self.error_message = error_message

  def _remove_structure_prefix(self, prefix, line):
    """Helper function for removing the structure prefix for parsing.

    Args:
      prefix: string, a _InstrumentationStructurePrefixes to remove from
        the raw output.
      line: string, the raw line from the instrumentation output.

    Returns:
      A string containing a key value pair descripting some property
      of the current instrumentation test method.
    """
    return line[len(prefix):].strip()

  def set_status_code(self, status_code_line):
    """Sets the status code for the instrumentation test method, used in
    determining the test result.

    Args:
      status_code_line: string, the raw instrumentation output line that
        contains the status code of the instrumentation block.
    """
    self._empty = False
    self.status_code = self._remove_structure_prefix(
        _InstrumentationStructurePrefixes.STATUS_CODE,
        status_code_line,
    )
    if self.status_code == _InstrumentationStatusCodes.START:
      self.begin_time = utils.get_current_epoch_time()

  def set_key(self, structure_prefix, key_line):
    """Sets the current key for the instrumentation block.

    For unknown keys, the key is added to the value list in order to
    better contextualize the value in the output.

    Args:
      structure_prefix: string, the structure prefix that was matched
        and that needs to be removed.
      key_line: string, the raw instrumentation output line that contains
        the key-value pair.
    """
    self._empty = False
    key_value = self._remove_structure_prefix(
        structure_prefix,
        key_line,
    )
    if '=' in key_value:
      (key, value) = key_value.split('=', 1)
      self.current_key = key
      if key in self.known_keys:
        self.known_keys[key].append(value)
      else:
        self.unknown_keys[key].append(key_value)

  def add_value(self, line):
    """Adds unstructured or multi-line value output to the current parsed
    instrumentation block for outputting later.

    Usually, this will add extra lines to the value list for the current
    key-value pair. However, sometimes, such as when instrumentation
    failed to start, output does not follow the structured prefix format.
    In this case, adding all of the output is still useful so that a user
    can debug the issue.

    Args:
      line: string, the raw instrumentation line to append to the value
        list.
    """
    # Don't count whitespace only lines.
    if line.strip():
      self._empty = False

    if self.current_key in self.known_keys:
      self.known_keys[self.current_key].append(line)
    else:
      self.unknown_keys[self.current_key].append(line)

  def transition_state(self, new_state):
    """Transitions or sets the current instrumentation block to the new
    parser state.

    Args:
      new_state: _InstrumentationBlockStates, the state that the parser
        should transition to.

    Returns:
      A new instrumentation block set to the new state, representing
      the start of parsing a new instrumentation test method.
      Alternatively, if the current instrumentation block represents the
      start of parsing a new instrumentation block (state UNKNOWN), then
      this returns the current instrumentation block set to the now
      known parsing state.
    """
    if self.state == _InstrumentationBlockStates.UNKNOWN:
      self.state = new_state
      return self
    else:
      next_block = _InstrumentationBlock(
          state=new_state,
          prefix=self.prefix,
          previous_instrumentation_block=self,
      )
      if self.status_code in _InstrumentationStatusCodeCategories.TIMING:
        next_block.begin_time = self.begin_time
      return next_block


class _InstrumentationBlockFormatter:
  """Takes an instrumentation block and converts it into a Mobly test
  result.
  """

  DEFAULT_INSTRUMENTATION_METHOD_NAME = 'instrumentation_method'

  def __init__(self, instrumentation_block):
    self._prefix = instrumentation_block.prefix
    self._status_code = instrumentation_block.status_code
    self._error_message = instrumentation_block.error_message
    self._known_keys = {}
    self._unknown_keys = {}
    for key, value in instrumentation_block.known_keys.items():
      self._known_keys[key] = '\n'.join(
          instrumentation_block.known_keys[key]).rstrip()
    for key, value in instrumentation_block.unknown_keys.items():
      self._unknown_keys[key] = '\n'.join(
          instrumentation_block.unknown_keys[key]).rstrip()
    self._begin_time = instrumentation_block.begin_time

  def _get_name(self):
    """Gets the method name of the test method for the instrumentation
    method block.

    Returns:
      A string containing the name of the instrumentation test method's
      test or a default name if no name was parsed.
    """
    if self._known_keys[_InstrumentationKnownStatusKeys.TEST]:
      return self._known_keys[_InstrumentationKnownStatusKeys.TEST]
    else:
      return self.DEFAULT_INSTRUMENTATION_METHOD_NAME

  def _get_class(self):
    """Gets the class name of the test method for the instrumentation
    method block.

    Returns:
      A string containing the class name of the instrumentation test
      method's test or empty string if no name was parsed. If a prefix
      was specified, then the prefix will be prepended to the class
      name.
    """
    class_parts = [
        self._prefix, self._known_keys[_InstrumentationKnownStatusKeys.CLASS]
    ]
    return '.'.join(filter(None, class_parts))

  def _get_full_name(self):
    """Gets the qualified name of the test method corresponding to the
    instrumentation block.

    Returns:
      A string containing the fully qualified name of the
      instrumentation test method. If parts are missing, then degrades
      steadily.
    """
    full_name_parts = [self._get_class(), self._get_name()]
    return '#'.join(filter(None, full_name_parts))

  def _get_details(self):
    """Gets the output for the detail section of the TestResultRecord.

    Returns:
      A string to set for a TestResultRecord's details.
    """
    detail_parts = [self._get_full_name(), self._error_message]
    return '\n'.join(filter(None, detail_parts))

  def _get_extras(self):
    """Gets the output for the extras section of the TestResultRecord.

    Returns:
      A string to set for a TestResultRecord's extras.
    """
    # Add empty line to start key-value pairs on a new line.
    extra_parts = ['']

    for value in self._unknown_keys.values():
      extra_parts.append(value)

    extra_parts.append(self._known_keys[_InstrumentationKnownStatusKeys.STREAM])
    extra_parts.append(
        self._known_keys[_InstrumentationKnownResultKeys.SHORTMSG])
    extra_parts.append(
        self._known_keys[_InstrumentationKnownResultKeys.LONGMSG])
    extra_parts.append(self._known_keys[_InstrumentationKnownStatusKeys.ERROR])

    if self._known_keys[
        _InstrumentationKnownStatusKeys.STACK] not in self._known_keys[
            _InstrumentationKnownStatusKeys.STREAM]:
      extra_parts.append(
          self._known_keys[_InstrumentationKnownStatusKeys.STACK])

    return '\n'.join(filter(None, extra_parts))

  def _is_failed(self):
    """Determines if the test corresponding to the instrumentation block
    failed.

    This method can not be used to tell if a test method passed and
    should not be used for such a purpose.

    Returns:
      A boolean indicating if the test method failed.
    """
    if self._status_code in _InstrumentationStatusCodeCategories.FAIL:
      return True
    elif (self._known_keys[_InstrumentationKnownStatusKeys.STACK] and
          self._status_code != _InstrumentationStatusCodes.ASSUMPTION_FAILURE):
      return True
    elif self._known_keys[_InstrumentationKnownStatusKeys.ERROR]:
      return True
    elif self._known_keys[_InstrumentationKnownResultKeys.SHORTMSG]:
      return True
    elif self._known_keys[_InstrumentationKnownResultKeys.LONGMSG]:
      return True
    else:
      return False

  def create_test_record(self, mobly_test_class):
    """Creates a TestResultRecord for the instrumentation block.

    Args:
      mobly_test_class: string, the name of the Mobly test case
        executing the instrumentation run.

    Returns:
      A TestResultRecord with an appropriate signals exception
      representing the instrumentation test method's result status.
    """
    details = self._get_details()
    extras = self._get_extras()

    tr_record = records.TestResultRecord(
        t_name=self._get_full_name(),
        t_class=mobly_test_class,
    )
    if self._begin_time:
      tr_record.begin_time = self._begin_time

    if self._is_failed():
      tr_record.test_fail(e=signals.TestFailure(details=details, extras=extras))
    elif self._status_code in _InstrumentationStatusCodeCategories.SKIPPED:
      tr_record.test_skip(e=signals.TestSkip(details=details, extras=extras))
    elif self._status_code in _InstrumentationStatusCodeCategories.PASS:
      tr_record.test_pass(e=signals.TestPass(details=details, extras=extras))
    elif self._status_code in _InstrumentationStatusCodeCategories.TIMING:
      if self._error_message:
        tr_record.test_error(
            e=signals.TestError(details=details, extras=extras))
      else:
        tr_record = None
    else:
      tr_record.test_error(e=signals.TestError(details=details, extras=extras))
    if self._known_keys[_InstrumentationKnownStatusKeys.STACK]:
      tr_record.termination_signal.stacktrace = self._known_keys[
          _InstrumentationKnownStatusKeys.STACK]
    return tr_record

  def has_completed_result_block_format(self, error_message):
    """Checks the instrumentation result block for a signal indicating
    normal completion.

    Args:
      error_message: string, the error message to give if the
        instrumentation run did not complete successfully.-

    Returns:
      A boolean indicating whether or not the instrumentation run passed
      or failed overall.

    Raises:
      signals.TestError: Error raised if the instrumentation run did not
        complete because of a crash or some other issue.
    """
    extras = self._get_extras()
    if _InstrumentationResultSignals.PASS in extras:
      return True
    elif _InstrumentationResultSignals.FAIL in extras:
      return False
    else:
      raise signals.TestError(details=error_message, extras=extras)


class InstrumentationTestMixin:
  """A mixin for Mobly test classes to inherit from for instrumentation tests.

  This class should be used in a subclass of both BaseTestClass and this class
  in order to provide instrumentation test capabilities. This mixin is
  explicitly for the case where the underlying BaseTestClass cannot be
  replaced with BaseInstrumentationTestClass. In general, prefer using
  BaseInstrumentationTestClass instead.

  Attributes:
    DEFAULT_INSTRUMENTATION_OPTION_PREFIX: string, the default prefix for
      instrumentation params contained within user params.
    DEFAULT_INSTRUMENTATION_ERROR_MESSAGE: string, the default error
      message to set if something has prevented something in the
      instrumentation test run from completing properly.
  """

  DEFAULT_INSTRUMENTATION_OPTION_PREFIX = 'instrumentation_option_'
  DEFAULT_INSTRUMENTATION_ERROR_MESSAGE = ('instrumentation run exited '
                                           'unexpectedly')

  def _previous_block_never_completed(self, current_block, previous_block,
                                      new_state):
    """Checks if the previous instrumentation method block completed.

    Args:
      current_block: _InstrumentationBlock, the current instrumentation
        block to check for being a different instrumentation test
        method.
      previous_block: _InstrumentationBlock, rhe previous
        instrumentation block to check for an incomplete status.
      new_state: _InstrumentationBlockStates, the next state for the
        parser, used to check for the instrumentation run ending
        with an incomplete test.

    Returns:
      A boolean indicating whether the previous instrumentation block
      completed executing.
    """
    if previous_block:
      previously_timing_block = (previous_block.status_code
                                 in _InstrumentationStatusCodeCategories.TIMING)
      currently_new_block = (current_block.status_code
                             == _InstrumentationStatusCodes.START or
                             new_state == _InstrumentationBlockStates.RESULT)
      return all([previously_timing_block, currently_new_block])
    else:
      return False

  def _create_formatters(self, instrumentation_block, new_state):
    """Creates the _InstrumentationBlockFormatters for outputting the
    instrumentation method block that have finished parsing.

    Args:
      instrumentation_block: _InstrumentationBlock, the current
        instrumentation method block to create formatters based upon.
      new_state: _InstrumentationBlockState, the next state that the
        parser will transition to.

    Returns:
      A list of the formatters tha need to create and add
      TestResultRecords to the test results.
    """
    formatters = []
    if self._previous_block_never_completed(
        current_block=instrumentation_block,
        previous_block=instrumentation_block.previous_instrumentation_block,
        new_state=new_state):
      instrumentation_block.previous_instrumentation_block.set_error_message(
          self.DEFAULT_INSTRUMENTATION_ERROR_MESSAGE)
      formatters.append(
          _InstrumentationBlockFormatter(
              instrumentation_block.previous_instrumentation_block))

    if not instrumentation_block.is_empty:
      formatters.append(_InstrumentationBlockFormatter(instrumentation_block))
    return formatters

  def _transition_instrumentation_block(
      self,
      instrumentation_block,
      new_state=_InstrumentationBlockStates.UNKNOWN):
    """Transitions and finishes the current instrumentation block.

    Args:
      instrumentation_block: _InstrumentationBlock, the current
        instrumentation block to finish.
      new_state: _InstrumentationBlockState, the next state for the
        parser to transition to.

    Returns:
      The new instrumentation block to use for storing parsed
      instrumentation output.
    """
    formatters = self._create_formatters(instrumentation_block, new_state)
    for formatter in formatters:
      test_record = formatter.create_test_record(self.TAG)
      if test_record:
        self.results.add_record(test_record)
        self.summary_writer.dump(test_record.to_dict(),
                                 records.TestSummaryEntryType.RECORD)
    return instrumentation_block.transition_state(new_state=new_state)

  def _parse_method_block_line(self, instrumentation_block, line):
    """Parses the instrumnetation method block's line.

    Args:
      instrumentation_block: _InstrumentationBlock, the current
        instrumentation method block.
      line: string, the raw instrumentation output line to parse.

    Returns:
      The next instrumentation block, which should be used to continue
      parsing instrumentation output.
    """
    if line.startswith(_InstrumentationStructurePrefixes.STATUS):
      instrumentation_block.set_key(_InstrumentationStructurePrefixes.STATUS,
                                    line)
      return instrumentation_block
    elif line.startswith(_InstrumentationStructurePrefixes.STATUS_CODE):
      instrumentation_block.set_status_code(line)
      return self._transition_instrumentation_block(instrumentation_block)
    elif line.startswith(_InstrumentationStructurePrefixes.RESULT):
      # Unexpected transition from method block -> result block
      instrumentation_block.set_key(_InstrumentationStructurePrefixes.RESULT,
                                    line)
      return self._parse_result_line(
          self._transition_instrumentation_block(
              instrumentation_block,
              new_state=_InstrumentationBlockStates.RESULT,
          ),
          line,
      )
    else:
      instrumentation_block.add_value(line)
      return instrumentation_block

  def _parse_result_block_line(self, instrumentation_block, line):
    """Parses the instrumentation result block's line.

    Args:
      instrumentation_block: _InstrumentationBlock, the instrumentation
        result block for the instrumentation run.
      line: string, the raw instrumentation output to add to the
        instrumenation result block's _InstrumentationResultBlocki
        object.

    Returns:
      The instrumentation result block for the instrumentation run.
    """
    instrumentation_block.add_value(line)
    return instrumentation_block

  def _parse_unknown_block_line(self, instrumentation_block, line):
    """Parses a line from the instrumentation output from the UNKNOWN
    parser state.

    Args:
      instrumentation_block: _InstrumentationBlock, the current
        instrumenation block, where the correct categorization it noti
        yet known.
      line: string, the raw instrumenation output line to be used to
        deteremine the correct categorization.

    Returns:
      The next instrumentation block to continue parsing with. Usually,
      this is the same instrumentation block but with the state
      transitioned appropriately.
    """
    if line.startswith(_InstrumentationStructurePrefixes.STATUS):
      return self._parse_method_block_line(
          self._transition_instrumentation_block(
              instrumentation_block,
              new_state=_InstrumentationBlockStates.METHOD,
          ),
          line,
      )
    elif (line.startswith(_InstrumentationStructurePrefixes.RESULT) or
          _InstrumentationStructurePrefixes.FAILED in line):
      return self._parse_result_block_line(
          self._transition_instrumentation_block(
              instrumentation_block,
              new_state=_InstrumentationBlockStates.RESULT,
          ),
          line,
      )
    else:
      # This would only really execute if instrumentation failed to start.
      instrumentation_block.add_value(line)
      return instrumentation_block

  def _parse_line(self, instrumentation_block, line):
    """Parses an arbitrary line from the instrumentation output based upon
    the current parser state.

    Args:
      instrumentation_block: _InstrumentationBlock, an instrumentation
        block with any of the possible parser states.
      line: string, the raw instrumentation output line to parse
        appropriately.

    Returns:
      The next instrumenation block to continue parsing with.
    """
    if instrumentation_block.state == _InstrumentationBlockStates.METHOD:
      return self._parse_method_block_line(instrumentation_block, line)
    elif instrumentation_block.state == _InstrumentationBlockStates.RESULT:
      return self._parse_result_block_line(instrumentation_block, line)
    else:
      return self._parse_unknown_block_line(instrumentation_block, line)

  def _finish_parsing(self, instrumentation_block):
    """Finishes parsing the instrumentation result block for the final
    instrumentation run status.

    Args:
      instrumentation_block: _InstrumentationBlock, the instrumentation
        result block for the instrumenation run. Potentially, thisi
        could actually be method block if the instrumentation outputi
        is malformed.

    Returns:
      A boolean indicating whether the instrumentation run completed
        with all the tests passing.

    Raises:
      signals.TestError: Error raised if the instrumentation failed to
        complete with either a pass or fail status.
    """
    formatter = _InstrumentationBlockFormatter(instrumentation_block)
    return formatter.has_completed_result_block_format(
        self.DEFAULT_INSTRUMENTATION_ERROR_MESSAGE)

  def parse_instrumentation_options(self, parameters=None):
    """Returns the options for the instrumentation test from user_params.

    By default, this method assume that the correct instrumentation options
    all start with DEFAULT_INSTRUMENTATION_OPTION_PREFIX.

    Args:
      parameters: dict, the key value pairs representing an assortment
        of parameters including instrumentation options. Usually,
        this argument will be from self.user_params.

    Returns:
      A dictionary of options/parameters for the instrumentation tst.
    """
    if parameters is None:
      return {}

    filtered_parameters = {}
    for parameter_key, parameter_value in parameters.items():
      if parameter_key.startswith(self.DEFAULT_INSTRUMENTATION_OPTION_PREFIX):
        option_key = parameter_key[len(self.
                                       DEFAULT_INSTRUMENTATION_OPTION_PREFIX):]
        filtered_parameters[option_key] = parameter_value
    return filtered_parameters

  def run_instrumentation_test(self,
                               device,
                               package,
                               options=None,
                               prefix=None,
                               runner=None):
    """Runs instrumentation tests on a device and creates test records.

    Args:
      device: AndroidDevice, the device to run instrumentation tests on.
      package: string, the package name of the instrumentation tests.
      options: dict, Instrumentation options for the instrumentation
        tests.
      prefix: string, an optional prefix for parser output for
        distinguishing between instrumentation test runs.
      runner: string, the runner to use for the instrumentation package,
        default to DEFAULT_INSTRUMENTATION_RUNNER.

    Returns:
      A boolean indicating whether or not all the instrumentation test
        methods passed.

    Raises:
      TestError if the instrumentation run crashed or if parsing the
        output failed.
    """
    # Dictionary hack to allow overwriting the instrumentation_block in the
    # parse_instrumentation closure
    instrumentation_block = [_InstrumentationBlock(prefix=prefix)]

    def parse_instrumentation(raw_line):
      line = raw_line.rstrip().decode('utf-8')
      logging.info(line)
      instrumentation_block[0] = self._parse_line(instrumentation_block[0],
                                                  line)

    device.adb.instrument(package=package,
                          options=options,
                          runner=runner,
                          handler=parse_instrumentation)

    return self._finish_parsing(instrumentation_block[0])


class BaseInstrumentationTestClass(InstrumentationTestMixin,
                                   base_test.BaseTestClass):
  """Base class for all instrumentation test classes to inherit from.

  This class extends the BaseTestClass to add functionality to run and parse
  the output of instrumentation runs.

  Attributes:
    DEFAULT_INSTRUMENTATION_OPTION_PREFIX: string, the default prefix for
      instrumentation params contained within user params.
    DEFAULT_INSTRUMENTATION_ERROR_MESSAGE: string, the default error
      message to set if something has prevented something in the
      instrumentation test run from completing properly.
  """
