"""
This bot uses the python library `howdoi` which is not a
dependency of Zulip. To use this module, you will have to
install it in your local machine. In your terminal, enter
the following command:

    $ sudo pip install howdoi --upgrade

Note:
    * You might have to use `pip3` if you are using python 3.
    * The install command would also download any dependency
      required by `howdoi`.
"""

import sys
import logging
from textwrap import fill
try:
    from howdoi.howdoi import howdoi
except ImportError:
    logging.error("Dependency missing!!\n%s" % (__doc__))
    sys.exit(0)


class HowdoiHandler(object):
    '''
    This plugin facilitates searching Stack Overflow for
    techanical answers based on the Python library `howdoi`.
    To get the best possible answer, only include keywords
    in your questions.

    There are two possible commands:
    * @howdowe > This would return the answer to the same
                 stream that it was called from.

    * @howdoi > The bot would send a private message to the
                user containing the answer.

    By default, howdoi only returns the coding section of the
    first search result if possible, to see the full answer
    from Stack Overflow, append a '!' to the commands.
    (ie '@howdoi!', '@howdowe!')
    '''

    MAX_LINE_LENGTH = 85

    def usage(self):
        return '''
            This plugin will allow users to get techanical
            answers from Stackoverflow. Users should preface
            their questions with one of the following:

                * @howdowe > Answer to the same stream
                * @howdoi > Answer via private message

                * @howdowe! OR @howdoi! > Full answer from SO
            '''

    def triage_message(self, message, client):
        cmd_list = ['@howdowe', '@howdoi', '@howdowe!', '@howdoi!']
        question = message['content']

        # This next line of code is defensive, as we never want
        # to get into an infinite loop of searching answers
        # from Stackoverflow!
        if message['sender_email'].startswith('howdoi'):
            return False

        is_howdoi = any([question.startswith(cmd) for cmd in cmd_list])

        return is_howdoi

    def line_wrap(self, string, length):
        lines = string.split("\n")

        wrapped = [(fill(line) if len(line) > length else line)
                   for line in lines]

        return "\n".join(wrapped).strip()

    def get_answer(self, command, query):
        question = query[len(command):].strip()
        result = howdoi(dict(
            query=question,
            num_answers=1,
            pos=1,
            all=command[-1] == '!',
            color=False
        ))
        _answer = self.line_wrap(result, HowdoiHandler.MAX_LINE_LENGTH)

        answer = "Answer to '%s':\n```\n%s\n```" % (question, _answer)

        return answer

    def handle_message(self, message, client, state_handler):
        question = message['content']

        if question.startswith('@howdowe!'):
            client.send_message(dict(
                type='stream',
                to=message['display_recipient'],
                subject=message['subject'],
                content=self.get_answer('@howdowe!', question)
            ))

        elif question.startswith('@howdoi!'):
            client.send_message(dict(
                type='private',
                to=message['sender_email'],
                content=self.get_answer('@howdoi!', question)
            ))

        elif question.startswith('@howdowe'):
            client.send_message(dict(
                type='stream',
                to=message['display_recipient'],
                subject=message['subject'],
                content=self.get_answer('@howdowe', question)
            ))

        elif question.startswith('@howdoi'):
            client.send_message(dict(
                type='private',
                to=message['sender_email'],
                content=self.get_answer('@howdoi', question)
            ))


handler_class = HowdoiHandler