docs: def send_command(
          self,
          command_string,
          expect_string=None,
          delay_factor=1,
          max_loops=500,
          auto_find_prompt=True,
          strip_prompt=True,
          strip_command=True,
          normalize=True,
          use_textfsm=False,
      ):
          """Execute command_string on the SSH channel using a pattern-based mechanism. Generally
          used for show commands. By default this method will keep waiting to receive data until the
          network device prompt is detected. The current network device prompt will be determined
          automatically.
  
          :param command_string: The command to be executed on the remote device.
          :type command_string: str
  
          :param expect_string: Regular expression pattern to use for determining end of output.
              If left blank will default to being based on router prompt.
          :type expect_string: str
  
          :param delay_factor: Multiplying factor used to adjust delays (default: 1).
          :type delay_factor: int
  
          :param max_loops: Controls wait time in conjunction with delay_factor. Will default to be
              based upon self.timeout.
          :type max_loops: int
  
          :param strip_prompt: Remove the trailing router prompt from the output (default: True).
          :type strip_prompt: bool
  
          :param strip_command: Remove the echo of the command from the output (default: True).
          :type strip_command: bool
  
          :param normalize: Ensure the proper enter is sent at end of command (default: True).
          :type normalize: bool
  
          :param use_textfsm: Process command output through TextFSM template (default: False).
          :type normalize: bool
          """
          # Time to delay in each read loop
          loop_delay = 0.2
  
          # Default to making loop time be roughly equivalent to self.timeout (support old max_loops
          # and delay_factor arguments for backwards compatibility).
          delay_factor = self.select_delay_factor(delay_factor)
          if delay_factor == 1 and max_loops == 500:
              # Default arguments are being used; use self.timeout instead
              max_loops = int(self.timeout / loop_delay)
  
          # Find the current router prompt
          if expect_string is None:
              if auto_find_prompt:
                  try:
                      prompt = self.find_prompt(delay_factor=delay_factor)
                  except ValueError:
                      prompt = self.base_prompt
              else:
                  prompt = self.base_prompt
              search_pattern = re.escape(prompt.strip())
          else:
              search_pattern = expect_string
  
          if normalize:
              command_string = self.normalize_cmd(command_string)
  
          time.sleep(delay_factor * loop_delay)
          self.clear_buffer()
          self.write_channel(command_string)
  
          i = 1
          output = ""
          past_three_reads = deque(maxlen=3)
          first_line_processed = False
  
          # Keep reading data until search_pattern is found or until max_loops is reached.
          while i <= max_loops:
              new_data = self.read_channel()
              if new_data:
                  if self.ansi_escape_codes:
                      new_data = self.strip_ansi_escape_codes(new_data)
  
                  output += new_data
                  past_three_reads.append(new_data)
  
                  # Case where we haven't processed the first_line yet (there is a potential issue
                  # in the first line (in cases where the line is repainted).
                  if not first_line_processed:
                      output, first_line_processed = self._first_line_handler(
                          output, search_pattern
                      )
                      # Check if we have already found our pattern
                      if re.search(search_pattern, output):
                          break
  
                  else:
                      # Check if pattern is in the past three reads
                      if re.search(search_pattern, "".join(past_three_reads)):
                          break
  
              time.sleep(delay_factor * loop_delay)
              i += 1
          else:  # nobreak
              raise IOError(
                  "Search pattern never detected in send_command_expect: {}".format(
                      search_pattern
                  )
              )
  
          output = self._sanitize_output(
              output,
              strip_command=strip_command,
              command_string=command_string,
              strip_prompt=strip_prompt,
          )
          if use_textfsm:
              output = get_structured_data(
                  output, platform=self.device_type, command=command_string.strip()
              )
          return output