"""
Abstract
--------

Working with the shell -- commands, input, and outputs -- is a common activity in Python development. The shell
component brings various utilities together to make working with the shell a pleasure.

Install
-------

Feedback requires colorama. Tables require tabulate.

.. code-block:: bash

    pip install colorama
    pip install tabulate

Usage
-----

Commands and Scripts
....................

This component encapsulates shell commands in an object-oriented fashion, making it easier to assemble, preview, and run
shell commands, and obtain the results.

Using a Command
^^^^^^^^^^^^^^^

The :py:class:`commonkit.shell.commands.Command` class provides a convenient, object-oriented representation of command
line execution.

.. code-block:: python

    from commonkit.shell import Command

    # A simple command.
    command = Command("ls -ls")

    # print(command.preview())

    if command.run():
        print(command.output)
        print("Your listing is above.")
    else:
        print("Error: %s" % command.error)

    exit(command.code)

    # Create /tmp/tmp.txt file.
    command = Command("touch tmp.txt", path="/tmp")
    command.run()

    # Using a prefix.
    command = Command("pg_dumpall -U postgres", prefix='export PGPASSWORD="mypassword"')
    command.run()

Quick and Easy Aborts
^^^^^^^^^^^^^^^^^^^^^

It is convenient to issue a message at the same time as calling ``exit()``.

.. code-block:: python

    from commonkit.shell import abort

    # doing something important ...
    # still doing something important ...
    # oh, snap! there's no way to recover from this, I guess I'll have to ...
    abort("I can't go on.")

Multiple Commands in a Script
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The :py:class:`commonkit.shell.scripts.Script` class may be used to bring related commands together:

.. code-block:: python

    from commonkit.shell import Script

    script = Script("example")
    script.add("touch tmp.txt", path="/tmp")
    script.add("pg_dumpall -U postgres", prefix='export PGPASSWORD="mypassword"')

    print(script)

Prompts
.......

The prompt library provides utilities for collecting user input on the command line.

Input Classes
^^^^^^^^^^^^^

The base :py:class:`commonkit.shell.prompts.Input` class forms the basis for collecting user input. It may be used on
its own, but the type-specific classes provide additional options and validation. The supported input types are:

- Boolean
- Email
- Float
- Integer
- Regex
- Secret
- String

Collecting Related Inputs
^^^^^^^^^^^^^^^^^^^^^^^^^

The :py:class:`commonkit.shell.prompts.Form` class may be used to collect related inputs together. This class is meant
to be extended with defined inputs.

.. code-block:: python

    from commonkit.shell import prompts

    class NewUserForm(prompts.Form):
        name = prompts.String("name", minimum=2)
        email = prompts.Email("email_address", required=True)
        password1 = prompts.Secret("password", required=True)
        password2 = prompts.Secret("password_again", required=True)

    form.prompt()
    print(form.values)

Ad Hoc Usage of Input
^^^^^^^^^^^^^^^^^^^^^

The input classes are supported by two (2) functions, which may be used on their own if desired.

A simple input looks like:

.. code-block:: python

    from commonkit.shell import get_input

    value = get_input("Enter Your Ideal Tea Time", default="5pm")
    print(value)

Choices may also be used:

.. code-block:: python

    from commonkit.shell import get_choice

    choices = [
        "3pm",
        "4pm",
        "5pm",
        "6pm",
    ]

    value = get_choice("Select Your Ideal Tea Time", choices=choices, default="5pm")
    print(value)

Tables
......

The tables library provides a means of creating tabular output in various formats.

.. code-block:: python

    from commonkit.shell.tables import TABLE_FORMAT, Table

    headings = [
        "Name",
        "Breed",
        "Origin",
        "Classification",
    ]

    table = Table(headings=headings, formatting=TABLE_FORMAT.RST)

    table.add(["Zoe", "Chihuahua", "Mexico", "Companion Dog"])
    table.add(["Button", "Kelpie", "Australia", "Herding Dog"])
    table.add(["Penny", "Husky", "Canada", "Northern Breed"])

    print(table)

Output is generated by `python-tabulate`_.

.. _python-tabulate: https://bitbucket.org/astanin/python-tabulate/src/master/

See :py:mod:`commonkit.shell.constants` for a full list of supported formats.

Feedback
........

The feedback package provides utilities for printing feedback.

.. note::
    This is *not* a substitute or alternative to logging. See the :py:mod:`commonkit.logging` package.

The following procedural utilities are provided:

- ``colorize()``: Used by color printing functions.
- ``blue()``: Print a message in blue.
- ``green()``: Print a message in green.
- ``hr()``: Print a horizontal rule.
- ``plain()``: Print a message in plain text.
- ``red()``: Print a message in red.
- ``yellow()``: Print a message in yellow.

The :py:class:`commonkit.shell.feedback.Feedback` class may be used to collect and print messages.

.. code-block:: python

    # Initialize feedback.
    from commonkit.shell.feedback import Feedback

    feedback = Feedback()

    # Logging feedback.
    feedback.blue("This message is informational.")
    feedback.green("Yay! It worked!")
    feedback.yellow("I think something may be wrong.")
    feedback.hr()
    feedback.red("Something is definitely wrong.")
    feedback.plain("Oh, well.")

    # Print feedback, for example, at the end of your script or at the end of a set of related statements.
    for message in feedback:
        print(message)

"""
from .commands import *
from .constants import *
from .prompts import get_choice, get_input
from .scripts import *
from .tables import Table
from .variables import *
from . import prompts

__version__ = "0.9.2-d"
