#!/usr/bin/env python3
"""
________________________________________________________________________.

:PROJECT: simple_installer

*A simple program installation library*

:details: This is a simple program installation library 
          including asking user descisions:
         - yes / no queries
         - text queries
         - simple help
         - default, predefined answers
         
         It also contains some convenient functions for 
         calling of system commands :
         - simple system command calling module
         - running setup.py
         - import and install if not available

:file:    simpleinstall.py

:author:  mark doerr (mark@ismeralda.org) :

:date: (creation)          20180310
:date: (last modification) 20180612

.. note::  to debug the setup.py installation, execute: 
           export DISTUTILS_DEBUG=TRUE
            
.. todo:: - OS/platform handling

________________________________________________________________________

**Copyright**:
  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 file is provided "AS IS" with NO WARRANTY OF ANY KIND,
  INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

  For further Information see COPYING file that comes with this distribution.
________________________________________________________________________
"""

import os
import sys
import logging

import subprocess
import logging

from distutils.core import run_setup
from distutils.util import strtobool

__version__ = "0.0.1"

def query_yes_no(question, default_answer="yes", help=""):
    """Ask user at stdin a yes or no question
    
    :param question: question text to user
    :param default_answer: should be "yes" or "no"
    :param help: help text string
    :return:  :type: bool
    """
    if default_answer == "yes":
        prompt_txt = "{question} [Y/n] ".format(question=question)
    elif default_answer == "no" : # explicit no
        prompt_txt = "{question} [y/N] ".format(question=question)
    else:
        raise ValueError("default_answer must be 'yes' or 'no'!")

    while True:
        try:
            answer = input(prompt_txt)
            if answer:
                if answer=="?":
                    print(help)
                    continue
                else:
                    return strtobool(answer)
            else :
                return strtobool(default_answer)
        except ValueError:
            sys.stderr.write("Please respond with 'yes' or 'no' "
                             "(or 'y' or 'n').\n")
        except KeyboardInterrupt:
            logging.error("Query interrupted by user, exiting now ...")
            exit(0)

def query(question, default_answer="", help=""):
    """Ask user a question
    
    :param question: question text to user
    :param default_answer: any default answering text string
    :param help:  help text string
    :return: stripped answer string
    """
    prompt_txt = "{question} [{default_answer}] ".format(question=question, default_answer=default_answer)

    while True:
        answer = input(prompt_txt).strip()
        
        if answer :
            if answer=="?":
                print(help)
                continue
            else :
                return answer
        else :
            return default_answer


def call(command=""):
    ''' Convenient command call: it splits the command string into tokens (default separator: space)
    
    :param command: the command to be executed by the system
    '''
    try:
        cmd_lst = command.split()
        
        subprocess.run(cmd_lst, check=True)
    except subprocess.CalledProcessError as err:
        logging.error('ERROR:', err)
        
        
def run(command="", parameters=[]):
    '''This version is closer to the subprocess version
    
    :param command: the command to be executed by the system
    :param parameters: parameters of the this command
    '''
    try:
        subprocess.run([command]+parameters, check=True, shell=True)  #stdout=subprocess.PIPE
    except subprocess.CalledProcessError as err:
        logging.error('ERROR:', err)

def runSetup(src_dir="", lib_dir=""):
    """running a setup.py file within a pyhton script 
       it requires a lot of things set...
       :param src_dir: directory containing the setup.py file
       :param lib_dir: directory containing the target lib directory
    """
    # all path settings seem to be required by run_setup and setup.py
    os.environ["PYTHONPATH"] = os.path.join(lib_dir, 'lib', 'python3.5', 'site-packages')
    sys.path.append(lib_dir)
    os.chdir(src_dir)
    setup_file = os.path.join(src_dir, 'setup.py')
    run_setup(setup_file,  script_args=['install', '--prefix', lib_dir ])
            
def installAndImport(package):
    """ This imports a package and 
        if not available, installs it first 
    """
    import importlib
    try:
        importlib.import_module(package)
    except ImportError:
        import pip
        pip.main(['install', package])
    finally:
        globals()[package] = importlib.import_module(package)
        

if __name__=="__main__":
    """simple usage and testing routine """

    answer_txt = query("What do you like ?", default_answer="Spam", help="HELP: Here you can say, what you like")

    answer_bool = query_yes_no("Do you really like |{0}| ?".format(answer_txt), help="HELP: Here you can confirm, what you like")

    if answer_bool:
        sys.stdout.write("Indeed, she really likes |{0}| !\n".format(answer_txt))
    else:
        sys.stdout.write("Well, what a pitty. She does not like {0} !\n".format(answer_txt))

    if query_yes_no("Anything else ?", default_answer="no"):
        answer_txt = query("What else do you like ?", default_answer="Eggs")

        sys.stdout.write("I will also get some |{0}| for you !\n".format(answer_txt))
    else:
        sys.stdout.write("You are welcome !\n")

