# 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(object):
  """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(object):
  """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(object):
  """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(object):
  """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(object):
  """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(object):
  """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(object):
  """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(object):
  """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(object):
  """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.
  """
