# Path: jubakit/_stdio.py
# class _StandardIO(object):
#   def get(cls):
#   def set(cls, stdin=None, stdout=None, stderr=None):
#   def print(cls, *args, **kwargs):
#   def printe(cls, *args, **kwargs):
#   def devnull(cls):
# 
# Path: jubakit/_cli/base.py
# class BaseCLI(ExtendedCmd):
#   """
#   A base class for CLI interface of all services.
#   """
# 
#   def __init__(self, shell, *args, **kwargs):
#     super(BaseCLI, self).__init__(*args, **kwargs)
# 
#     self._sh = shell
# 
#     # Set help sentences.
#     self.doc_header = "Commands:"
#     self.undoc_header = "Commands (no help available):"
#     self.misc_header = "Documents:"
#     self.nohelp = "No help available for %s."
# 
#     # Register aliases.
#     self.register_alias('EOF', 'do_exit')
#     self.register_alias('ls', 'do_help')
#     self.register_alias('shell', 'shell_command')
# 
#   #################################################################
#   # Override methods to tweak CLI behavior
#   #################################################################
# 
#   def emptyline(self):
#     """
#     By default, empty line causes the previous command to run again.
#     This overrides the default handler for emptyline so it behaves like an usual shell.
#     """
#     pass
# 
#   def postcmd(self, stop, line):
#     """
#     After a single command is executed, we discard the connection if not in
#     keepalive mode.
#     """
#     if not self._sh._keepalive:
#       self._sh.disconnect()
#       self._sh.connect()
#     return stop
# 
#   def default(self, line):
#     """
#     Raise exception for unhandled commands.
#     """
#     raise CLIUnknownCommandException(line)
# 
#   #################################################################
#   # Common interfaces for Jubatus CLI
#   #################################################################
# 
#   @classmethod
#   def _name(cls):
#     """
#     Returns the name of the service (e.g., `classifier`).
#     You must override this in subclasses.
#     """
#     raise NotImplementedError
# 
#   def _verbose(self, msg):
#     """
#     Outputs logs only when in verbose mode.
#     """
#     if self._sh._verbose:
#       print(msg)
# 
#   @property
#   def client(self):
#     """
#     Returns the client instance.
#     """
#     return self._sh.get_client()
# 
#   #################################################################
#   # Built-in shell commands
#   #################################################################
# 
#   @Arguments()
#   def do_exit(self):
#     """Syntax: exit
#     Exits the shell.  You can also use EOF (Ctrl-D).
#     """
#     print()
#     return True
# 
#   def help_help(self):
#     print(
#     """Syntax: help [command]
#     Displays the list of commands available.
#     If ``command`` is specified, displays the help for the command."""
#     )
# 
#   def shell_command(self, param):
#     """
#     Runs the command in the *real* shell.
#     """
#     subprocess.call(param, shell=True)
# 
# class CLIInvalidatedException(Exception):
#   """
#   Notify Shell to regenerate CLI instance.
#   """
#   pass
# 
# class CLIUnknownCommandException(Exception):
#   """
#   Notify Shell that unknown command is specified.
#   """
#   pass


import sys
import socket
import optparse
import msgpackrpc
import jubatus
from .compat import *
from ._stdio import print, get_stdio
from ._cli.base import BaseCLI, CLIInvalidatedException, CLIUnknownCommandException
  # Cached references for Jubatus Client classes.
  _client_classes = {}

  # Error message.
  _INTERFACE_MISMATCH_ERROR = \
    'Interface mismatch error detected.  ' \
    'This error occured because either your version of Jubatus Python ' \
    'client library is not compatible with the server you are ' \
    'connecting to, or using an incompatible shell (for example, ' \
    'using Classifier shell against Anomaly server.)\n' \
    'Version compatibility information can be found at:\n' \
    '  https://github.com/jubatus/jubatus/wiki/Client-Compatibility-and-Documentation'

  def __init__(self, host, port, cluster, service, **kwargs):
    """
    Creates a new shell environment using parameters specified.

    If ``service`` is ``None``, it will be automatically probed.
    """
    self._host = host
    self._port = port
    self._cluster = cluster
    self._service = None

    self._client = None
    self._timeout = kwargs.get('timeout', 10)
    self._keepalive = kwargs.get('keepalive', False)
    self._verbose = kwargs.get('verbose', False)
    self._prompt_format = kwargs.get('prompt', self._PS)
    self._input = kwargs.get('input', None)

# Path: jubakit/_stdio.py
# class _StandardIO(object):
#   def get(cls):
#   def set(cls, stdin=None, stdout=None, stderr=None):
#   def print(cls, *args, **kwargs):
#   def printe(cls, *args, **kwargs):
#   def devnull(cls):
# 
# Path: jubakit/_cli/base.py
# class BaseCLI(ExtendedCmd):
#   """
#   A base class for CLI interface of all services.
#   """
# 
#   def __init__(self, shell, *args, **kwargs):
#     super(BaseCLI, self).__init__(*args, **kwargs)
# 
#     self._sh = shell
# 
#     # Set help sentences.
#     self.doc_header = "Commands:"
#     self.undoc_header = "Commands (no help available):"
#     self.misc_header = "Documents:"
#     self.nohelp = "No help available for %s."
# 
#     # Register aliases.
#     self.register_alias('EOF', 'do_exit')
#     self.register_alias('ls', 'do_help')
#     self.register_alias('shell', 'shell_command')
# 
#   #################################################################
#   # Override methods to tweak CLI behavior
#   #################################################################
# 
#   def emptyline(self):
#     """
#     By default, empty line causes the previous command to run again.
#     This overrides the default handler for emptyline so it behaves like an usual shell.
#     """
#     pass
# 
#   def postcmd(self, stop, line):
#     """
#     After a single command is executed, we discard the connection if not in
#     keepalive mode.
#     """
#     if not self._sh._keepalive:
#       self._sh.disconnect()
#       self._sh.connect()
#     return stop
# 
#   def default(self, line):
#     """
#     Raise exception for unhandled commands.
#     """
#     raise CLIUnknownCommandException(line)
# 
#   #################################################################
#   # Common interfaces for Jubatus CLI
#   #################################################################
# 
#   @classmethod
#   def _name(cls):
#     """
#     Returns the name of the service (e.g., `classifier`).
#     You must override this in subclasses.
#     """
#     raise NotImplementedError
# 
#   def _verbose(self, msg):
#     """
#     Outputs logs only when in verbose mode.
#     """
#     if self._sh._verbose:
#       print(msg)
# 
#   @property
#   def client(self):
#     """
#     Returns the client instance.
#     """
#     return self._sh.get_client()
# 
#   #################################################################
#   # Built-in shell commands
#   #################################################################
# 
#   @Arguments()
#   def do_exit(self):
#     """Syntax: exit
#     Exits the shell.  You can also use EOF (Ctrl-D).
#     """
#     print()
#     return True
# 
#   def help_help(self):
#     print(
#     """Syntax: help [command]
#     Displays the list of commands available.
#     If ``command`` is specified, displays the help for the command."""
#     )
# 
#   def shell_command(self, param):
#     """
#     Runs the command in the *real* shell.
#     """
#     subprocess.call(param, shell=True)
# 
# class CLIInvalidatedException(Exception):
#   """
#   Notify Shell to regenerate CLI instance.
#   """
#   pass
# 
# class CLIUnknownCommandException(Exception):
#   """
#   Notify Shell that unknown command is specified.
#   """
#   pass


# Path: jubakit/shell.py
import sys
import socket
import optparse
import msgpackrpc
import jubatus
from .compat import *
from ._stdio import print, get_stdio
from ._cli.base import BaseCLI, CLIInvalidatedException, CLIUnknownCommandException

  # Cached references for Jubatus Client classes.
  _client_classes = {}

  # Error message.
  _INTERFACE_MISMATCH_ERROR = \
    'Interface mismatch error detected.  ' \
    'This error occured because either your version of Jubatus Python ' \
    'client library is not compatible with the server you are ' \
    'connecting to, or using an incompatible shell (for example, ' \
    'using Classifier shell against Anomaly server.)\n' \
    'Version compatibility information can be found at:\n' \
    '  https://github.com/jubatus/jubatus/wiki/Client-Compatibility-and-Documentation'

  def __init__(self, host, port, cluster, service, **kwargs):
    """
    Creates a new shell environment using parameters specified.

    If ``service`` is ``None``, it will be automatically probed.
    """
    self._host = host
    self._port = port
    self._cluster = cluster
    self._service = None

    self._client = None
    self._timeout = kwargs.get('timeout', 10)
    self._keepalive = kwargs.get('keepalive', False)
    self._verbose = kwargs.get('verbose', False)
    self._prompt_format = kwargs.get('prompt', self._PS)
    self._input = kwargs.get('input', None)

    self._output = kwargs.get('output', get_stdio()[1])  # stdout