#!/usr/bin/python2
#
# Copyright 2010 Google Inc. All Rights Reserved.
#
# 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.

"""Template based text parser.

This module implements a parser, intended to be used for converting
human readable text, such as command output from a router CLI, into
a list of records, containing values extracted from the input text.

A simple template language is used to describe a state machine to
parse a specific type of text input, returning a record of values
for each input entity.

Import it to ~/file/client/common_lib/cros/.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

__version__ = '0.3.2'

import getopt
import inspect
import re
import string
import sys


class Error(Exception):
  """Base class for errors."""


class Usage(Exception):
  """Error in command line execution."""


class TextFSMError(Error):
  """Error in the FSM state execution."""


class TextFSMTemplateError(Error):
  """Errors while parsing templates."""


# The below exceptions are internal state change triggers
# and not used as Errors.
class FSMAction(Exception):
  """Base class for actions raised with the FSM."""


class SkipRecord(FSMAction):
  """Indicate a record is to be skipped."""


class SkipValue(FSMAction):
  """Indicate a value is to be skipped."""


class TextFSMOptions(object):
  """Class containing all valid TextFSMValue options.

  Each nested class here represents a TextFSM option. The format
  is "option<name>".
  Each class may override any of the methods inside the OptionBase class.

  A user of this module can extend options by subclassing
  TextFSMOptionsBase, adding the new option class(es), then passing
  that new class to the TextFSM constructor with the 'option_class'
  argument.
  """

  class OptionBase(object):
    """Factory methods for option class.

    Attributes:
      value: A TextFSMValue, the parent Value.
    """

    def __init__(self, value):
      self.value = value

    @property
    def name(self):
      return self.__class__.__name__.replace('option', '')

    def OnCreateOptions(self):
      """Called after all options have been parsed for a Value."""

    def OnClearVar(self):
      """Called when value has been cleared."""

    def OnClearAllVar(self):
      """Called when a value has clearalled."""

    def OnAssignVar(self):
      """Called when a matched value is being assigned."""

    def OnGetValue(self):
      """Called when the value name is being requested."""

    def OnSaveRecord(self):
      """Called just prior to a record being committed."""

  @classmethod
  def ValidOptions(cls):
    """Returns a list of valid option names."""
    valid_options = []
    for obj_name in dir(cls):
      obj = getattr(cls, obj_name)
      if inspect.isclass(obj) and issubclass(obj, cls.OptionBase):
        valid_options.append(obj_name)
    return valid_options

  @classmethod
  def GetOption(cls, name):
    """Returns the class of the requested option name."""
    return getattr(cls, name)

  class Required(OptionBase):
    """The Value must be non-empty for the row to be recorded."""

    def OnSaveRecord(self):
      if not self.value.value:
        raise SkipRecord

  class Filldown(OptionBase):
    """Value defaults to the previous line's value."""

    def OnCreateOptions(self):
      self._myvar = None

    def OnAssignVar(self):
      self._myvar = self.value.value

    def OnClearVar(self):
      self.value.value = self._myvar

    def OnClearAllVar(self):
      self._myvar = None

  class Fillup(OptionBase):
    """Like Filldown, but upwards until it finds a non-empty entry."""

    def OnAssignVar(self):
      # If value is set, copy up the results table, until we
      # see a set item.
      if self.value.value:
        # Get index of relevant result column.
        value_idx = self.value.fsm.values.index(self.value)
        # Go up the list from the end until we see a filled value.
        # pylint: disable=protected-access
        for result in reversed(self.value.fsm._result):
          if result[value_idx]:
            # Stop when a record has this column already.
            break
          # Otherwise set the column value.
          result[value_idx] = self.value.value

  class Key(OptionBase):
    """Value constitutes part of the Key of the record."""

  class List(OptionBase):
    """Value takes the form of a list."""

    def OnCreateOptions(self):
      self.OnClearAllVar()

    def OnAssignVar(self):
      self._value.append(self.value.value)

    def OnClearVar(self):
      if 'Filldown' not in self.value.OptionNames():
        self._value = []

    def OnClearAllVar(self):
      self._value = []

    def OnSaveRecord(self):
      self.value.value = list(self._value)


class TextFSMValue(object):
  """A TextFSM value.

  A value has syntax like:

  'Value Filldown,Required helloworld (.*)'

  Where 'Value' is a keyword.
  'Filldown' and 'Required' are options.
  'helloworld' is the value name.
  '(.*) is the regular expression to match in the input data.

  Attributes:
    max_name_len: (int), maximum character length os a variable name.
    name: (str), Name of the value.
    options: (list), A list of current Value Options.
    regex: (str), Regex which the value is matched on.
    template: (str), regexp with named groups added.
    fsm: A TextFSMBase(), the containing FSM.
    value: (str), the current value.
  """
  # The class which contains valid options.

  def __init__(self, fsm=None, max_name_len=48, options_class=None):
    """Initialise a new TextFSMValue."""
    self.max_name_len = max_name_len
    self.name = None
    self.options = []
    self.regex = None
    self.value = None
    self.fsm = fsm
    self._options_cls = options_class

  def AssignVar(self, value):
    """Assign a value to this Value."""
    self.value = value
    # Call OnAssignVar on options.
    _ = [option.OnAssignVar() for option in self.options]

  def ClearVar(self):
    """Clear this Value."""
    self.value = None
    # Call OnClearVar on options.
    _ = [option.OnClearVar() for option in self.options]

  def ClearAllVar(self):
    """Clear this Value."""
    self.value = None
    # Call OnClearAllVar on options.
    _ = [option.OnClearAllVar() for option in self.options]

  def Header(self):
    """Fetch the header name of this Value."""
    # Call OnGetValue on options.
    _ = [option.OnGetValue() for option in self.options]
    return self.name

  def OptionNames(self):
    """Returns a list of option names for this Value."""
    return [option.name for option in self.options]

  def Parse(self, value):
    """Parse a 'Value' declaration.

    Args:
      value: String line from a template file, must begin with 'Value '.

    Raises:
      TextFSMTemplateError: Value declaration contains an error.

    """

    value_line = value.split(' ')
    if len(value_line) < 3:
      raise TextFSMTemplateError('Expect at least 3 tokens on line.')

    if not value_line[2].startswith('('):
      # Options are present
      options = value_line[1]
      for option in options.split(','):
        self._AddOption(option)
      # Call option OnCreateOptions callbacks
      _ = [option.OnCreateOptions() for option in self.options]

      self.name = value_line[2]
      self.regex = ' '.join(value_line[3:])
    else:
      # There were no valid options, so there are no options.
      # Treat this argument as the name.
      self.name = value_line[1]
      self.regex = ' '.join(value_line[2:])

    if len(self.name) > self.max_name_len:
      raise TextFSMTemplateError(
          "Invalid Value name '%s' or name too long." % self.name)

    if (not re.match(r'^\(.*\)$', self.regex) or
        self.regex.count('(') != self.regex.count(')')):
      raise TextFSMTemplateError(
          "Value '%s' must be contained within a '()' pair." % self.regex)

    self.template = re.sub(r'^\(', '(?P<%s>' % self.name, self.regex)

  def _AddOption(self, name):
    """Add an option to this Value.

    Args:
      name: (str), the name of the Option to add.

    Raises:
      TextFSMTemplateError: If option is already present or
        the option does not exist.
    """

    # Check for duplicate option declaration
    if name in [option.name for option in self.options]:
      raise TextFSMTemplateError('Duplicate option "%s"' % name)

    # Create the option object
    try:
      option = self._options_cls.GetOption(name)(self)
    except AttributeError:
      raise TextFSMTemplateError('Unknown option "%s"' % name)

    self.options.append(option)

  def OnSaveRecord(self):
    """Called just prior to a record being committed."""
    _ = [option.OnSaveRecord() for option in self.options]

  def __str__(self):
    """Prints out the FSM Value, mimic the input file."""

    if self.options:
      return 'Value %s %s %s' % (
          ','.join(self.OptionNames()),
          self.name,
          self.regex)
    else:
      return 'Value %s %s' % (self.name, self.regex)


class CopyableRegexObject(object):
  """Like a re.RegexObject, but can be copied."""
  # pylint: disable=C6409

  def __init__(self, pattern):
    self.pattern = pattern
    self.regex = re.compile(pattern)

  def match(self, *args, **kwargs):
    return self.regex.match(*args, **kwargs)

  def sub(self, *args, **kwargs):
    return self.regex.sub(*args, **kwargs)

  def __copy__(self):
    return CopyableRegexObject(self.pattern)

  def __deepcopy__(self, unused_memo):
    return self.__copy__()


class TextFSMRule(object):
  """A rule in each FSM state.

  A value has syntax like:

      ^<regexp> -> Next.Record State2

  Where '<regexp>' is a regular expression.
  'Next' is a Line operator.
  'Record' is a Record operator.
  'State2' is the next State.

  Attributes:
    match: Regex to match this rule.
    regex: match after template substitution.
    line_op: Operator on input line on match.
    record_op: Operator on output record on match.
    new_state: Label to jump to on action
    regex_obj: Compiled regex for which the rule matches.
    line_num: Integer row number of Value.
  """
  # Implicit default is '(regexp) -> Next.NoRecord'
  MATCH_ACTION = re.compile(r'(?P<match>.*)(\s->(?P<action>.*))')

  # The structure to the right of the '->'.
  LINE_OP = ('Continue', 'Next', 'Error')
  RECORD_OP = ('Clear', 'Clearall', 'Record', 'NoRecord')

  # Line operators.
  LINE_OP_RE = '(?P<ln_op>%s)' % '|'.join(LINE_OP)
  # Record operators.
  RECORD_OP_RE = '(?P<rec_op>%s)' % '|'.join(RECORD_OP)
  # Line operator with optional record operator.
  OPERATOR_RE = r'(%s(\.%s)?)' % (LINE_OP_RE, RECORD_OP_RE)
  # New State or 'Error' string.
  NEWSTATE_RE = r'(?P<new_state>\w+|\".*\")'

  # Compound operator (line and record) with optional new state.
  ACTION_RE = re.compile(r'\s+%s(\s+%s)?$' % (OPERATOR_RE, NEWSTATE_RE))
  # Record operator with optional new state.
  ACTION2_RE = re.compile(r'\s+%s(\s+%s)?$' % (RECORD_OP_RE, NEWSTATE_RE))
  # Default operators with optional new state.
  ACTION3_RE = re.compile(r'(\s+%s)?$' % (NEWSTATE_RE))

  def __init__(self, line, line_num=-1, var_map=None):
    """Initialise a new rule object.

    Args:
      line: (str), a template rule line to parse.
      line_num: (int), Optional line reference included in error reporting.
      var_map: Map for template (${var}) substitutions.

    Raises:
      TextFSMTemplateError: If 'line' is not a valid format for a Value entry.
    """
    self.match = ''
    self.regex = ''
    self.regex_obj = None
    self.line_op = ''              # Equivalent to 'Next'.
    self.record_op = ''            # Equivalent to 'NoRecord'.
    self.new_state = ''            # Equivalent to current state.
    self.line_num = line_num

    line = line.strip()
    if not line:
      raise TextFSMTemplateError('Null data in FSMRule. Line: %s'
                                 % self.line_num)

    # Is there '->' action present.
    match_action = self.MATCH_ACTION.match(line)
    if match_action:
      self.match = match_action.group('match')
    else:
      self.match = line

    # Replace ${varname} entries.
    self.regex = self.match
    if var_map:
      try:
        self.regex = string.Template(self.match).substitute(var_map)
      except (ValueError, KeyError):
        raise TextFSMTemplateError(
            "Duplicate or invalid variable substitution: '%s'. Line: %s." %
            (self.match, self.line_num))

    try:
      # Work around a regression in Python 2.6 that makes RE Objects uncopyable.
      self.regex_obj = CopyableRegexObject(self.regex)
    except re.error:
      raise TextFSMTemplateError(
          "Invalid regular expression: '%s'. Line: %s." %
          (self.regex, self.line_num))

    # No '->' present, so done.
    if not match_action:
      return

    # Attempt to match line.record operation.
    action_re = self.ACTION_RE.match(match_action.group('action'))
    if not action_re:
      # Attempt to match record operation.
      action_re = self.ACTION2_RE.match(match_action.group('action'))
      if not action_re:
        # Math implicit defaults with an optional new state.
        action_re = self.ACTION3_RE.match(match_action.group('action'))
        if not action_re:
          # Last attempt, match an optional new state only.
          raise TextFSMTemplateError("Badly formatted rule '%s'. Line: %s." %
                                     (line, self.line_num))

    # We have an Line operator.
    if 'ln_op' in action_re.groupdict() and action_re.group('ln_op'):
      self.line_op = action_re.group('ln_op')

    # We have a record operator.
    if 'rec_op' in action_re.groupdict() and action_re.group('rec_op'):
      self.record_op = action_re.group('rec_op')

    # A new state was specified.
    if 'new_state' in action_re.groupdict() and action_re.group('new_state'):
      self.new_state = action_re.group('new_state')

    # Only 'Next' (or implicit 'Next') line operator can have a new_state.
    # But we allow error to have one as a warning message so we are left
    # checking that Continue does not.
    if self.line_op == 'Continue' and self.new_state:
      raise TextFSMTemplateError(
          "Action '%s' with new state %s specified. Line: %s."
          % (self.line_op, self.new_state, self.line_num))

    # Check that an error message is present only with the 'Error' operator.
    if self.line_op != 'Error' and self.new_state:
      if not re.match(r'\w+', self.new_state):
        raise TextFSMTemplateError(
            'Alphanumeric characters only in state names. Line: %s.'
            % (self.line_num))

  def __str__(self):
    """Prints out the FSM Rule, mimic the input file."""

    operation = ''
    if self.line_op and self.record_op:
      operation = '.'

    operation = '%s%s%s' % (self.line_op, operation, self.record_op)

    if operation and self.new_state:
      new_state = ' ' + self.new_state
    else:
      new_state = self.new_state

    # Print with implicit defaults.
    if not (operation or new_state):
      return '  %s' % self.match

    # Non defaults.
    return '  %s -> %s%s' % (self.match, operation, new_state)


class TextFSM(object):
  """Parses template and creates Finite State Machine (FSM).

  Attributes:
    states: (str), Dictionary of FSMState objects.
    values: (str), List of FSMVariables.
    value_map: (map), For substituting values for names in the expressions.
    header: Ordered list of values.
    state_list: Ordered list of valid states.
  """
  # Variable and State name length.
  MAX_NAME_LEN = 48
  comment_regex = re.compile(r'^\s*#')
  state_name_re = re.compile(r'^(\w+)$')
  _DEFAULT_OPTIONS = TextFSMOptions

  def __init__(self, template, options_class=_DEFAULT_OPTIONS):
    """Initialises and also parses the template file."""

    self._options_cls = options_class
    self.states = {}
    # Track order of state definitions.
    self.state_list = []
    self.values = []
    self.value_map = {}
    # Track where we are for error reporting.
    self._line_num = 0
    # Run FSM in this state
    self._cur_state = None
    # Name of the current state.
    self._cur_state_name = None

    # Read and parse FSM definition.
    # Restore the file pointer once done.
    try:
      self._Parse(template)
    finally:
      template.seek(0)

    # Initialise starting data.
    self.Reset()

  def __str__(self):
    """Returns the FSM template, mimic the input file."""

    result = '\n'.join([str(value) for value in self.values])
    result += '\n'

    for state in self.state_list:
      result += '\n%s\n' % state
      state_rules = '\n'.join([str(rule) for rule in self.states[state]])
      if state_rules:
        result += state_rules + '\n'

    return result

  def Reset(self):
    """Preserves FSM but resets starting state and current record."""

    # Current state is Start state.
    self._cur_state = self.states['Start']
    self._cur_state_name = 'Start'

    # Clear table of results and current record.
    self._result = []
    self._ClearAllRecord()

  @property
  def header(self):
    """Returns header."""
    return self._GetHeader()

  def _GetHeader(self):
    """Returns header."""
    header = []
    for value in self.values:
      try:
        header.append(value.Header())
      except SkipValue:
        continue
    return header

  def _GetValue(self, name):
    """Returns the TextFSMValue object natching the requested name."""
    for value in self.values:
      if value.name == name:
        return value

  def _AppendRecord(self):
    """Adds current record to result if well formed."""

    # If no Values then don't output.
    if not self.values:
      return

    cur_record = []
    for value in self.values:
      try:
        value.OnSaveRecord()
      except SkipRecord:
        self._ClearRecord()
        return
      except SkipValue:
        continue

      # Build current record into a list.
      cur_record.append(value.value)

    # If no Values in template or whole record is empty then don't output.
    if len(cur_record) == (cur_record.count(None) + cur_record.count([])):
      return

    # Replace any 'None' entries with null string ''.
    while None in cur_record:
      cur_record[cur_record.index(None)] = ''

    self._result.append(cur_record)
    self._ClearRecord()

  def _Parse(self, template):
    """Parses template file for FSM structure.

    Args:
      template: Valid template file.

    Raises:
      TextFSMTemplateError: If template file syntax is invalid.
    """

    if not template:
      raise TextFSMTemplateError('Null template.')

    # Parse header with Variables.
    self._ParseFSMVariables(template)

    # Parse States.
    while self._ParseFSMState(template):
      pass

    # Validate destination states.
    self._ValidateFSM()

  def _ParseFSMVariables(self, template):
    """Extracts Variables from start of template file.

    Values are expected as a contiguous block at the head of the file.
    These will be line separated from the State definitions that follow.

    Args:
      template: Valid template file, with Value definitions at the top.

    Raises:
      TextFSMTemplateError: If syntax or semantic errors are found.
    """

    self.values = []

    for line in template:
      self._line_num += 1
      line = line.rstrip()

      # Blank line signifies end of Value definitions.
      if not line:
        return

      # Skip commented lines.
      if self.comment_regex.match(line):
        continue

      if line.startswith('Value '):
        try:
          value = TextFSMValue(
              fsm=self, max_name_len=self.MAX_NAME_LEN,
              options_class=self._options_cls)
          value.Parse(line)
        except TextFSMTemplateError as error:
          raise TextFSMTemplateError('%s Line %s.' % (error, self._line_num))

        if value.name in self.header:
          raise TextFSMTemplateError(
              "Duplicate declarations for Value '%s'. Line: %s."
              % (value.name, self._line_num))

        try:
          self._ValidateOptions(value)
        except TextFSMTemplateError as error:
          raise TextFSMTemplateError('%s Line %s.' % (error, self._line_num))

        self.values.append(value)
        self.value_map[value.name] = value.template
      # The line has text but without the 'Value ' prefix.
      elif not self.values:
        raise TextFSMTemplateError('No Value definitions found.')
      else:
        raise TextFSMTemplateError(
            'Expected blank line after last Value entry. Line: %s.'
            % (self._line_num))

  def _ValidateOptions(self, value):
    """Checks that combination of Options is valid."""
    # Always passes in base class.
    pass

  def _ParseFSMState(self, template):
    """Extracts State and associated Rules from body of template file.

    After the Value definitions the remainder of the template is
    state definitions. The routine is expected to be called iteratively
    until no more states remain - indicated by returning None.

    The routine checks that the state names are a well formed string, do
    not clash with reserved names and are unique.

    Args:
      template: Valid template file after Value definitions
      have already been read.

    Returns:
      Name of the state parsed from file. None otherwise.

    Raises:
      TextFSMTemplateError: If any state definitions are invalid.
    """

    if not template:
      return

    state_name = ''
    # Strip off extra white space lines (including comments).
    for line in template:
      self._line_num += 1
      line = line.rstrip()

      # First line is state definition
      if line and not self.comment_regex.match(line):
         # Ensure statename has valid syntax and is not a reserved word.
        if (not self.state_name_re.match(line) or
            len(line) > self.MAX_NAME_LEN or
            line in TextFSMRule.LINE_OP or
            line in TextFSMRule.RECORD_OP):
          raise TextFSMTemplateError("Invalid state name: '%s'. Line: %s"
                                     % (line, self._line_num))

        state_name = line
        if state_name in self.states:
          raise TextFSMTemplateError("Duplicate state name: '%s'. Line: %s"
                                     % (line, self._line_num))
        self.states[state_name] = []
        self.state_list.append(state_name)
        break

    # Parse each rule in the state.
    for line in template:
      self._line_num += 1
      line = line.rstrip()

      # Finish rules processing on blank line.
      if not line:
        break

      if self.comment_regex.match(line):
        continue

      # A rule within a state, starts with whitespace
      if not (line.startswith('  ^') or line.startswith('\t^')):
        raise TextFSMTemplateError(
            "Missing white space or carat ('^') before rule. Line: %s" %
            self._line_num)

      self.states[state_name].append(
          TextFSMRule(line, self._line_num, self.value_map))

    return state_name

  def _ValidateFSM(self):
    """Checks state names and destinations for validity.

    Each destination state must exist, be a valid name and
    not be a reserved name.
    There must be a 'Start' state and if 'EOF' or 'End' states are specified,
    they must be empty.

    Returns:
      True if FSM is valid.

    Raises:
      TextFSMTemplateError: If any state definitions are invalid.
    """

    # Must have 'Start' state.
    if 'Start' not in self.states:
      raise TextFSMTemplateError("Missing state 'Start'.")

    # 'End/EOF' state (if specified) must be empty.
    if self.states.get('End'):
      raise TextFSMTemplateError("Non-Empty 'End' state.")

    if self.states.get('EOF'):
      raise TextFSMTemplateError("Non-Empty 'EOF' state.")

    # Remove 'End' state.
    if 'End' in self.states:
      del self.states['End']
      self.state_list.remove('End')

    # Ensure jump states are all valid.
    for state in self.states:
      for rule in self.states[state]:
        if rule.line_op == 'Error':
          continue

        if not rule.new_state or rule.new_state in ('End', 'EOF'):
          continue

        if rule.new_state not in self.states:
          raise TextFSMTemplateError(
              "State '%s' not found, referenced in state '%s'" %
              (rule.new_state, state))

    return True

  def ParseText(self, text, eof=True):
    """Passes CLI output through FSM and returns list of tuples.

    First tuple is the header, every subsequent tuple is a row.

    Args:
      text: (str), Text to parse with embedded newlines.
      eof: (boolean), Set to False if we are parsing only part of the file.
            Suppresses triggering EOF state.

    Raises:
      TextFSMError: An error occurred within the FSM.

    Returns:
      List of Lists.
    """

    lines = []
    if text:
      lines = text.splitlines()

    for line in lines:
      self._CheckLine(line)
      if self._cur_state_name in ('End', 'EOF'):
        break

    if self._cur_state_name != 'End' and 'EOF' not in self.states and eof:
      # Implicit EOF performs Next.Record operation.
      # Suppressed if Null EOF state is instantiated.
      self._AppendRecord()

    return self._result

  def _CheckLine(self, line):
    """Passes the line through each rule until a match is made.

    Args:
      line: A string, the current input line.
    """
    for rule in self._cur_state:
      matched = self._CheckRule(rule, line)
      if matched:
        for value in matched.groupdict():
          self._AssignVar(matched, value)

        if self._Operations(rule):
          # Not a Continue so check for state transition.
          if rule.new_state:
            if rule.new_state not in ('End', 'EOF'):
              self._cur_state = self.states[rule.new_state]
            self._cur_state_name = rule.new_state
          break

  def _CheckRule(self, rule, line):
    """Check a line against the given rule.

    This is a separate method so that it can be overridden by
    a debugging tool.

    Args:
      rule: A TextFSMRule(), the rule to check.
      line: A str, the line to check.

    Returns:
      A regex match object.
    """
    return rule.regex_obj.match(line)

  def _AssignVar(self, matched, value):
    """Assigns variable into current record from a matched rule.

    If a record entry is a list then append, otherwise values are replaced.

    Args:
      matched: (regexp.match) Named group for each matched value.
      value: (str) The matched value.
    """
    self._GetValue(value).AssignVar(matched.group(value))

  def _Operations(self, rule):
    """Operators on the data record.

    Operators come in two parts and are a '.' separated pair:

      Operators that effect the input line or the current state (line_op).
        'Next'      Get next input line and restart parsing (default).
        'Continue'  Keep current input line and continue resume parsing.
        'Error'     Unrecoverable input discard result and raise Error.

      Operators that affect the record being built for output (record_op).
        'NoRecord'  Does nothing (default)
        'Record'    Adds the current record to the result.
        'Clear'     Clears non-Filldown data from the record.
        'Clearall'  Clears all data from the record.

    Args:
      rule: FSMRule object.

    Returns:
      True if state machine should restart state with new line.

    Raises:
      TextFSMError: If Error state is encountered.
    """
    # First process the Record operators.
    if rule.record_op == 'Record':
      self._AppendRecord()

    elif rule.record_op == 'Clear':
      # Clear record.
      self._ClearRecord()

    elif rule.record_op == 'Clearall':
      # Clear all record entries.
      self._ClearAllRecord()

    # Lastly process line operators.
    if rule.line_op == 'Error':
      if rule.new_state:
        raise TextFSMError('Error: %s. Line: %s.'
                           % (rule.new_state, rule.line_num))

      raise TextFSMError('State Error raised. Line: %s.'
                         % (rule.line_num))

    elif rule.line_op == 'Continue':
      # Continue with current line without returning to the start of the state.
      return False

    # Back to start of current state with a new line.
    return True

  def _ClearRecord(self):
    """Remove non 'Filldown' record entries."""
    _ = [value.ClearVar() for value in self.values]

  def _ClearAllRecord(self):
    """Remove all record entries."""
    _ = [value.ClearAllVar() for value in self.values]

  def GetValuesByAttrib(self, attribute):
    """Returns the list of values that have a particular attribute."""

    if attribute not in self._options_cls.ValidOptions():
      raise ValueError("'%s': Not a valid attribute." % attribute)

    result = []
    for value in self.values:
      if attribute in value.OptionNames():
        result.append(value.name)

    return result


def main(argv=None):
  """Validate text parsed with FSM or validate an FSM via command line."""

  if argv is None:
    argv = sys.argv

  try:
    opts, args = getopt.getopt(argv[1:], 'h', ['help'])
  except getopt.error as msg:
    raise Usage(msg)

  for opt, _ in opts:
    if opt in ('-h', '--help'):
      print(__doc__)
      print(help_msg)
      return 0

  if not args or len(args) > 4:
    raise Usage('Invalid arguments.')

  # If we have an argument, parse content of file and display as a template.
  # Template displayed will match input template, minus any comment lines.
  with open(args[0], 'r') as template:
    fsm = TextFSM(template)
    print('FSM Template:\n%s\n' % fsm)

    if len(args) > 1:
      # Second argument is file with example cli input.
      # Prints parsed tabular result.
      with open(args[1], 'r') as f:
        cli_input = f.read()

      table = fsm.ParseText(cli_input)
      print('FSM Table:')
      result = str(fsm.header) + '\n'
      for line in table:
        result += str(line) + '\n'
      print(result, end='')

  if len(args) > 2:
    # Compare tabular result with data in third file argument.
    # Exit value indicates if processed data matched expected result.
    with open(args[2], 'r') as f:
      ref_table = f.read()

    if ref_table != result:
      print('Data mis-match!')
      return 1
    else:
      print('Data match!')


if __name__ == '__main__':
  help_msg = '%s [--help] template [input_file [output_file]]\n' % sys.argv[0]
  try:
    sys.exit(main())
  except Usage as err:
    print(err, file=sys.stderr)
    print('For help use --help', file=sys.stderr)
    sys.exit(2)
  except (IOError, TextFSMError, TextFSMTemplateError) as err:
    print(err, file=sys.stderr)
    sys.exit(2)
