"""
CLI (Command Line Interface) classes for RTM Importer.
"""

from __future__ import absolute_import, print_function, unicode_literals

__docformat__ = 'reStructuredText'

import webbrowser

from dear_astrid.rtm.importer import *

__all__ = [
  'RTMAPIError',
  'AuthError',
  'CLIAuth',
  'CLIImporter',
]

# TODO: Is there a better way to share class methods than multiple inheritance?
class CLIHelpers(object):
  """Add helper methods for cli input/output to classes."""

  # pylint: disable=no-self-use
  def prompt(self, text):
    """Prompt the user for a value."""
    try:
      # py2
      answer = raw_input(text)
    except NameError:
      # pylint: disable=bad-builtin
      # py3k
      answer = input(text)
    return answer

  def message(self, *args, **kwargs):
    """Print each argument to STDOUT."""
    for arg in args:
      print(arg, **kwargs)


class CLIAuth(BaseAuth, CLIHelpers):
  """Authorize RTM importer using the command line as an interface."""

  def __init__(self, key, secret, cache=None):
    BaseAuth.__init__(self, key, secret)
    # TODO: self.cache = cache if cache else os.path.expanduser()

  # TODO: store auth token (~/.dear_astrid ?) for repeats
  def get_token_from_file(self):
    return False

  def get_token_from_api(self):
    """Get token from API by opening a web browser."""

    # Instantiate api with fake token to get url.
    api = self.api('dear_astrid', test_login=False)
    url = api.getAuthURL()

    webbrowser.open(url, True, True)
    self.message(
      "You must authorize this app with RTM.",
      "If a browser does not open visit this URL:",
      url,
    )
    self.prompt('Press Enter after you have authorized this app through RTM.')

    return api.getToken()

  def auth(self):
    token = self.get_token_from_file()
    if token:
      # Make sure token is still authorized.
      try:
        return self.api(token)
      except RTMAPIError:
        self.message("Previous token is no longer valid.")

    token = self.get_token_from_api()
    try:
      return self.api(token)
    except RTMAPIError:
      raise AuthError("Failed to authorize app with RTM.")


class CLIImporter(Importer, CLIHelpers):
  """Import tasks into RTM on the command line."""

  default_auth = CLIAuth

  def display_task(self, task, spec='{0}', **kwargs):
    """Print description of task using SmartAdd property or task name."""
    self.message(
      spec.format(task.get('smart_add', task.get('name', '(unknown)'))),
      **kwargs
    )

  def import_tasks(self, tasks):
    """Confirm task list before importing."""

    for task in tasks:
      self.display_task(task, spec=' {0}')

    cont = self.prompt('Import tasks? (y/n):')
    if not cont.lower().startswith('y'):
      return

    super(CLIImporter, self).import_tasks(tasks)

  def add_task(self, task):
    """Print description of task before adding and show progress indicator."""

    self.display_task(task, spec='Adding: {0}', end='')

    super(CLIImporter, self).add_task(task)

    # Append newline.
    self.message('')

  @property
  def rtm(self):
    # self.before_rtm ?
    self.message('.', end='')
    return super(CLIImporter, self).rtm

"""
CLI (Command Line Interface) classes for RTM Importer.
"""

from __future__ import absolute_import, print_function, unicode_literals

__docformat__ = 'reStructuredText'

import webbrowser

from dear_astrid.rtm.importer import *

__all__ = [
  'RTMAPIError',
  'AuthError',
  'CLIAuth',
  'CLIImporter',
]

# TODO: Is there a better way to share class methods than multiple inheritance?
class CLIHelpers(object):
  """Add helper methods for cli input/output to classes."""

  # pylint: disable=no-self-use
  def prompt(self, text):
    """Prompt the user for a value."""
    try:
      # py2
      answer = raw_input(text)
    except NameError:
      # pylint: disable=bad-builtin
      # py3k
      answer = input(text)
    return answer

  def message(self, *args, **kwargs):
    """Print each argument to STDOUT."""
    for arg in args:
      print(arg, **kwargs)


class CLIAuth(BaseAuth, CLIHelpers):
  """Authorize RTM importer using the command line as an interface."""

  def __init__(self, key, secret, cache=None):
    BaseAuth.__init__(self, key, secret)
    # TODO: self.cache = cache if cache else os.path.expanduser()

  # TODO: store auth token (~/.dear_astrid ?) for repeats
  def get_token_from_file(self):
    return False

  def get_token_from_api(self):
    """Get token from API by opening a web browser."""

    # Instantiate api with fake token to get url.
    api = self.api('dear_astrid', test_login=False)
    url = api.getAuthURL()

    webbrowser.open(url, True, True)
    self.message(
      "You must authorize this app with RTM.",
      "If a browser does not open visit this URL:",
      url,
    )
    self.prompt('Press Enter after you have authorized this app through RTM.')

    return api.getToken()

  def auth(self):
    token = self.get_token_from_file()
    if token:
      # Make sure token is still authorized.
      try:
        return self.api(token)
      except RTMAPIError:
        self.message("Previous token is no longer valid.")

    token = self.get_token_from_api()
    try:
      return self.api(token)
    except RTMAPIError:
      raise AuthError("Failed to authorize app with RTM.")


class CLIImporter(Importer, CLIHelpers):
  """Import tasks into RTM on the command line."""

  default_auth = CLIAuth

  def display_task(self, task, spec='{0}', **kwargs):
    """Print description of task using SmartAdd property or task name."""
    self.message(
      spec.format(task.get('smart_add', task.get('name', '(unknown)'))),
      **kwargs
    )

  def import_tasks(self, tasks):
    """Confirm task list before importing."""

    for task in tasks:
      self.display_task(task, spec=' {0}')

    cont = self.prompt('Import tasks? (y/n):')
    if not cont.lower().startswith('y'):
      return

    super(CLIImporter, self).import_tasks(tasks)

  def add_task(self, task):
    """Print description of task before adding and show progress indicator."""

    self.display_task(task, spec='Adding: {0}', end='')

    super(CLIImporter, self).add_task(task)

    # Append newline.
    self.message('')

  @property
  def rtm(self):
    # self.before_rtm ?
    self.message('.', end='')
    return super(CLIImporter, self).rtm

CLI (Command Line Interface) classes for RTM Importer. # TODO: Is there a better way to share class methods than multiple inheritance? Add helper methods for cli input/output to classes. # pylint: disable=no-self-use Prompt the user for a value. # py2 # pylint: disable=bad-builtin # py3k Print each argument to STDOUT. Authorize RTM importer using the command line as an interface. # TODO: self.cache = cache if cache else os.path.expanduser() # TODO: store auth token (~/.dear_astrid ?) for repeats Get token from API by opening a web browser. # Instantiate api with fake token to get url. # Make sure token is still authorized. Import tasks into RTM on the command line. Print description of task using SmartAdd property or task name. Confirm task list before importing. Print description of task before adding and show progress indicator. # Append newline. # self.before_rtm ?