#!/usr/bin/env python
"""
 Copyright (C) 2010-2013, Ryan Fan

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Library General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""
import shlex
import sys

from getlogs.libs import utils

CODE_STDOUT = 'stdout'
CODE_STDERR = 'stderr'
CODE_QUIT = 'quit'


class Command(object):
    def __init__(self, config):
        self.config = config
        self.progress_step = 0
        self.progress_hint = "Executing..."

    def _run_cmd_unblocked(self, cmd, inputs, timeout, progress_callback):
        raise NotImplementedError

    def _run_cmd_blocked(self, cmd, inputs, timeout, progress_callback):
        raise NotImplementedError

    def _run_bkcmd_unblocked(self, cmd, inputs, timeout, progress_callback):
        raise NotImplementedError

    def _run_bkcmd_blocked(self, cmd, inputs, timeout, progress_callback):
        raise NotImplementedError

    def _cmd_err_result(self, error_msg):
        """  return standard error result  """
        if not error_msg:
            error_msg = ""

        return -1, None, str(error_msg)

    def _cmd_result(self, status_code, stdout, stderr):
        return status_code, stdout.rstrip("\n"), stderr.rstrip("\n")

    def process_cmd_string(self, cmd_string):
        """Parses command strings and returns a Popen-ready list."""
        # Prepare arguments.
        if isinstance(cmd_string, str):
            splitter = shlex.shlex(cmd_string)
            splitter.whitespace = '|'
            splitter.whitespace_split = True
            cmd_list = []

            while True:
                token = splitter.get_token()
                if token:
                    cmd_list.append(token)
                else:
                    break

            cmd_list = list(map(shlex.split, cmd_list))

        return cmd_list

    def progress_cmd(self):
        """ Show animate progress info when executing cmd  """
        utils.reset_console_line()
        self.progress_step += 1

        #  animate the waiting symbol
        waiting_symbol_list = ['/', '-', '\\', '|']
        progress_bar = '\r%s %s' % (
            waiting_symbol_list[(self.progress_step % 4)], self.progress_hint)

        sys.stdout.write(progress_bar)
        sys.stdout.flush()

    def run_cmd(self, cmd, inputs=None, timeout=None,blocking=True,
                progress_callback=None):
        """ Run command in foreground """
        if not blocking:
            if not progress_callback:
                callback = self.progress_cmd
            else:
                callback = progress_callback

            return self._run_cmd_unblocked(
                cmd, inputs, timeout, callback)

        return self._run_cmd_blocked(cmd, inputs)

    def run_background_cmd(self, cmd, inputs=None, timeout=None, blocking=True,
                           progress_callback=None):
        """ Run command in background(separate thread) """

        if not blocking:
            if not progress_callback:
                callback = self.progress_cmd
            else:
                callback = progress_callback

            return self._run_bkcmd_unblocked(
                cmd, inputs, timeout, callback)

        return self._run_bkcmd_blocked(cmd, inputs)

