# 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.
    """
