# Path: mdk/command.py
# class Command(object):
#     """Represents a command"""
# 
#     _arguments = [
#             (
#                 ['foo'],
#                 {
#                     'help': 'I\'m an argument'
#                 }
#             ),
#             (
#                 ['-b', '--bar'],
#                 {
#                     'action': 'store_true',
#                     'help': 'I\'m a flag'
#                 }
#             )
#         ]
#     _description = 'Undocumented command'
# 
#     __C = None
#     __Wp = None
# 
#     def __init__(self, config):
#         self.__C = config
# 
#     def argumentError(self, message):
#         raise CommandArgumentError(message)
# 
#     @property
#     def arguments(self):
#         return self._arguments
# 
#     @property
#     def C(self):
#         return self.__C
# 
#     @property
#     def description(self):
#         return self._description
# 
#     def run(self, args):
#         return True
# 
#     @property
#     def Wp(self):
#         if not self.__Wp:
#             from .workplace import Workplace
#             self.__Wp = Workplace()
#         return self.__Wp
# 
# Path: mdk/tools.py
# def process(cmd, cwd=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE):
#     if type(cmd) != list:
#         cmd = shlex.split(str(cmd))
#     logging.debug(' '.join(cmd))
#     try:
#         proc = subprocess.Popen(cmd, cwd=cwd, stdout=stdout, stderr=stderr, encoding='utf-8')
#         (out, err) = proc.communicate()
#     except KeyboardInterrupt as e:
#         proc.kill()
#         raise e
#     return (proc.returncode, out.decode('utf-8') if type(out) == bytes else out, err)
# 
# class ProcessInThread(threading.Thread):
#     """Executes a process in a separate thread"""
# 
#     cmd = None
#     cwd = None
#     stdout = None
#     stderr = None
#     _kill = False
#     _pid = None
# 
#     def __init__(self, cmd, cwd=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE):
#         threading.Thread.__init__(self)
#         if type(cmd) != 'list':
#             cmd = shlex.split(str(cmd))
#         self.cmd = cmd
#         self.cwd = cwd
#         self.stdout = stdout
#         self.stderr = stderr
# 
#     def kill(self):
#         os.kill(self._pid, signal.SIGKILL)
# 
#     def run(self):
#         logging.debug(' '.join(self.cmd))
#         proc = subprocess.Popen(self.cmd, cwd=self.cwd, stdout=self.stdout, stderr=self.stderr)
#         self._pid = proc.pid
#         while True:
#             if proc.poll():
#                 break
# 
#             # Reading the output seems to prevent the process to hang.
#             if self.stdout == subprocess.PIPE:
#                 proc.stdout.read(1)
# 
# def downloadProcessHook(count, size, total):
#     """Hook to report the downloading a file using urllib.urlretrieve"""
#     if count <= 0:
#         return
#     downloaded = int((count * size) / (1024))
#     total = int(total / (1024)) if total != 0 else '?'
#     if downloaded > total:
#         downloaded = total
#     sys.stderr.write("\r  %sKB / %sKB" % (downloaded, total))
#     sys.stderr.flush()
# 
# def question(q, default=None, options=None, password=False):
#     """Asks the user a question, and return the answer"""
#     text = q
#     if default != None:
#         text = text + ' [%s]' % str(default)
# 
#     if password:
#         i = getpass.getpass('%s\n   ' % text)
#     else:
#         i = input('%s\n  ' % text)
# 
#     if i.strip() == '':
#         return default
#     else:
#         if options != None and i not in options:
#             return question(q, default, options)
#         return i
# 
# def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
#     """
#     Use as key when naturally sorting elements.
# 
#     Source: https://stackoverflow.com/a/16090640/867720
#     """
#     return [int(text) if text.isdigit() else text.lower() for text in _nsre.split(s)]


import os
import urllib.request, urllib.parse, urllib.error
import re
import logging
import gzip
from tempfile import gettempdir
from time import sleep
from ..command import Command
from ..tools import process, ProcessInThread, downloadProcessHook, question, natural_sort_key
            seleniumPath = args.selenium
        elif args.seleniumforcedl or (not nojavascript and not os.path.isfile(seleniumPath)):
            logging.info('Attempting to find a download for Selenium')
            seleniumStorageUrl = 'https://selenium-release.storage.googleapis.com/'
            url = urllib.request.urlopen(seleniumStorageUrl)
            content = url.read().decode('utf-8')
            matches = sorted(re.findall(r'[a-z0-9._-]+/selenium-server-standalone-[0-9.]+\.jar', content, re.I),
                             key=natural_sort_key)
            if len(matches) > 0:
                seleniumUrl = seleniumStorageUrl + matches[-1]
                logging.info('Downloading Selenium from %s' % seleniumUrl)
                if (logging.getLogger().level <= logging.INFO):
                    urllib.request.urlretrieve(seleniumUrl, seleniumPath, downloadProcessHook)
                    # Force a new line after the hook display
                    logging.info('')
                else:
                    urllib.request.urlretrieve(seleniumUrl, seleniumPath)
            else:
                logging.warning('Could not locate Selenium server to download')

        if not nojavascript and not os.path.isfile(seleniumPath):
            raise Exception('Selenium file %s does not exist')

        # Run cli
        try:

            # If Oracle, ask the user for a Behat prefix, if not set.
            prefix = M.get('behat_prefix')
            if M.get('dbtype') == 'oci' and (args.force or not prefix or len(prefix) > 2):
                while not prefix or len(prefix) > 2:

# Path: mdk/command.py
# class Command(object):
#     """Represents a command"""
# 
#     _arguments = [
#             (
#                 ['foo'],
#                 {
#                     'help': 'I\'m an argument'
#                 }
#             ),
#             (
#                 ['-b', '--bar'],
#                 {
#                     'action': 'store_true',
#                     'help': 'I\'m a flag'
#                 }
#             )
#         ]
#     _description = 'Undocumented command'
# 
#     __C = None
#     __Wp = None
# 
#     def __init__(self, config):
#         self.__C = config
# 
#     def argumentError(self, message):
#         raise CommandArgumentError(message)
# 
#     @property
#     def arguments(self):
#         return self._arguments
# 
#     @property
#     def C(self):
#         return self.__C
# 
#     @property
#     def description(self):
#         return self._description
# 
#     def run(self, args):
#         return True
# 
#     @property
#     def Wp(self):
#         if not self.__Wp:
#             from .workplace import Workplace
#             self.__Wp = Workplace()
#         return self.__Wp
# 
# Path: mdk/tools.py
# def process(cmd, cwd=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE):
#     if type(cmd) != list:
#         cmd = shlex.split(str(cmd))
#     logging.debug(' '.join(cmd))
#     try:
#         proc = subprocess.Popen(cmd, cwd=cwd, stdout=stdout, stderr=stderr, encoding='utf-8')
#         (out, err) = proc.communicate()
#     except KeyboardInterrupt as e:
#         proc.kill()
#         raise e
#     return (proc.returncode, out.decode('utf-8') if type(out) == bytes else out, err)
# 
# class ProcessInThread(threading.Thread):
#     """Executes a process in a separate thread"""
# 
#     cmd = None
#     cwd = None
#     stdout = None
#     stderr = None
#     _kill = False
#     _pid = None
# 
#     def __init__(self, cmd, cwd=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE):
#         threading.Thread.__init__(self)
#         if type(cmd) != 'list':
#             cmd = shlex.split(str(cmd))
#         self.cmd = cmd
#         self.cwd = cwd
#         self.stdout = stdout
#         self.stderr = stderr
# 
#     def kill(self):
#         os.kill(self._pid, signal.SIGKILL)
# 
#     def run(self):
#         logging.debug(' '.join(self.cmd))
#         proc = subprocess.Popen(self.cmd, cwd=self.cwd, stdout=self.stdout, stderr=self.stderr)
#         self._pid = proc.pid
#         while True:
#             if proc.poll():
#                 break
# 
#             # Reading the output seems to prevent the process to hang.
#             if self.stdout == subprocess.PIPE:
#                 proc.stdout.read(1)
# 
# def downloadProcessHook(count, size, total):
#     """Hook to report the downloading a file using urllib.urlretrieve"""
#     if count <= 0:
#         return
#     downloaded = int((count * size) / (1024))
#     total = int(total / (1024)) if total != 0 else '?'
#     if downloaded > total:
#         downloaded = total
#     sys.stderr.write("\r  %sKB / %sKB" % (downloaded, total))
#     sys.stderr.flush()
# 
# def question(q, default=None, options=None, password=False):
#     """Asks the user a question, and return the answer"""
#     text = q
#     if default != None:
#         text = text + ' [%s]' % str(default)
# 
#     if password:
#         i = getpass.getpass('%s\n   ' % text)
#     else:
#         i = input('%s\n  ' % text)
# 
#     if i.strip() == '':
#         return default
#     else:
#         if options != None and i not in options:
#             return question(q, default, options)
#         return i
# 
# def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
#     """
#     Use as key when naturally sorting elements.
# 
#     Source: https://stackoverflow.com/a/16090640/867720
#     """
#     return [int(text) if text.isdigit() else text.lower() for text in _nsre.split(s)]


# Path: mdk/commands/behat.py
import os
import urllib.request, urllib.parse, urllib.error
import re
import logging
import gzip
from tempfile import gettempdir
from time import sleep
from ..command import Command
from ..tools import process, ProcessInThread, downloadProcessHook, question, natural_sort_key

            seleniumPath = args.selenium
        elif args.seleniumforcedl or (not nojavascript and not os.path.isfile(seleniumPath)):
            logging.info('Attempting to find a download for Selenium')
            seleniumStorageUrl = 'https://selenium-release.storage.googleapis.com/'
            url = urllib.request.urlopen(seleniumStorageUrl)
            content = url.read().decode('utf-8')
            matches = sorted(re.findall(r'[a-z0-9._-]+/selenium-server-standalone-[0-9.]+\.jar', content, re.I),
                             key=natural_sort_key)
            if len(matches) > 0:
                seleniumUrl = seleniumStorageUrl + matches[-1]
                logging.info('Downloading Selenium from %s' % seleniumUrl)
                if (logging.getLogger().level <= logging.INFO):
                    urllib.request.urlretrieve(seleniumUrl, seleniumPath, downloadProcessHook)
                    # Force a new line after the hook display
                    logging.info('')
                else:
                    urllib.request.urlretrieve(seleniumUrl, seleniumPath)
            else:
                logging.warning('Could not locate Selenium server to download')

        if not nojavascript and not os.path.isfile(seleniumPath):
            raise Exception('Selenium file %s does not exist')

        # Run cli
        try:

            # If Oracle, ask the user for a Behat prefix, if not set.
            prefix = M.get('behat_prefix')
            if M.get('dbtype') == 'oci' and (args.force or not prefix or len(prefix) > 2):
                while not prefix or len(prefix) > 2:

                    prefix = question('What prefix would you like to use? (Oracle, max 2 chars)')