# Help
# Output a help topic.
#
# To Do:  Output the obscured text within a class instantiation. So rather than
# just outputting obscured text, output 'Hidden('obscured-text'). Also, accept
# obscured text within its class and try to decode it using the class name, so
# if GPG("ciphertext") then it will use GPG to decode it even if user does not
# provide the encoding.
#
# Also implement script class that uses a personal password. Call this Encrypt
# or PersonalEncrypt.

# License {{{1
# Copyright (C) 2016 Kenneth S. Kundert
#
# 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 3 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program.  If not, see http://www.gnu.org/licenses/.


# Imports {{{1
from .conceal import Conceal
from .command import Command
from .config import get_setting
from .utilities import pager, two_columns
from inform import error, output
from textwrap import dedent

# HelpMessage base class {{{1
class HelpMessage:
    # get_name() {{{2
    @classmethod
    def get_name(cls):
        try:
            return cls.name.lower()
        except AttributeError:
            # consider converting lower to upper case transitions in __name__ to
            # dashes.
            return cls.__name__.lower()

    # topics {{{2
    @classmethod
    def topics(cls):
        for sub in cls.__subclasses__():
            yield sub

    # show {{{2
    @classmethod
    def show(cls, name=None):
        if name:
            name = name.lower()
            command = Command.find(name)
            if command:
                return pager(command.help())
            for topic in cls.topics():
               if name == topic.get_name():
                   return pager(topic.help())
            error('topic not found.', culprit=name)
        else:
            cls.help()

    # summarize {{{2
    @classmethod
    def summarize(cls, width=16):
        summaries = []
        for topic in sorted(cls.topics(), key=lambda topic: topic.get_name()):
            summaries.append(two_columns(topic.get_name(), topic.DESCRIPTION))
        return '\n'.join(summaries)

    # help {{{2
    @classmethod
    def help(cls):
        output('Available commands:')
        output(Command.summarize())

        output('\nAvailable topics:')
        output(cls.summarize())


# Overview class {{{1
class Overview(HelpMessage):
    DESCRIPTION = "overview of Avendesora"

    @staticmethod
    def help():
        text = dedent("""
            Avendesora is password utility that can store your account
            information and generate account passwords and produce them from the
            command line.  It can also be configured to autotype your username
            and password into the current window so that you can log in with a
            simple keystroke.

            Avendesora is capable of generating passwords (character-based
            passcodes) or pass phrases (word-based passcodes).  Pass phrases are
            generally preferred if you have a choice, but many websites will not
            take them.  The benefit of pass phrases is that they are relatively
            easy to remember and type, and they are very secure.  The pass
            phrases generated by Avendesora generally consist of four words,
            each word is drawn from a dictionary of 10,000 words.  Thus, even if
            a bad guy knew that four lower case words were being used for your
            pass phrase, there are still 10,000,000,000,000,000 possible
            combinations for him to try (this represents a mini‐ mum entropy of
            53 bits).  Using six words results in 80 bits of entropy, which
            meets the threshold recommended by NIST for the most secure pass
            phrases. For more on this, see 'How Much Entropy is Enough' below.

            For another perspective on the attractiveness of pass phrases, see
            http://xkcd.com/936/.

            Unlike password vaults, Avendesora produces a highly unpredictable
            password from a master password and the name of the account for
            which the password is to be used. The process is completely
            repeatable. If you give the same master password and account name,
            you will get the same password. As such, the passwords do not have
            to be saved; instead they are regenerated on the fly.

            As a password generator, Avendesora provides three important
            advantages over conventional password vaults.  First, it allows
            groups of people to share access to accounts without having to
            securely share each password.  Instead, one member of the group
            creates a master password that is securely shared with the group
            once.  From then on any member of the group can create a new
            account, share the name of the account, and all members will know
            the password needed to access the account. The second advantage is
            that it opens up the possibility of using high-quality passwords for
            stealth accounts, which are accounts where you remember the name of
            the account but do not store any information about even the
            existence of the account on your computer.  With Avendesora, you
            only need to remember the name of the account and it will regenerate
            the password for you. This is perfect for your TrueCrypt hidden
            volume password.  Finally, by securely storing a small amount of
            infor‐ mation, perhaps on a piece of paper in your safe-deposit box,
            you can often recover most if not all of your passwords even if you
            somehow lose your accounts file. You can even recover passwords that
            were created after you created your backup. This is because
            Avendesora combines the master password with some easily recon‐
            structed information, such as the account name, to create the
            password. If you save the master password, the rest should be
            recoverable.

            To use it, one creates a file that contains information about each
            of his or her non-stealth accounts.  Among that information would be
            information that controls how the passwords are generated. This file
            is generally not encrypted, though you can encrypt it if you like).
            Another file is created that contains one or more master passwords.
            This file is always GPG encrypted.

            The intent is for these files to not include the passwords for your
            accounts.  Rather, the passwords are regenerated when needed from
            the account information and from the master password. This makes it
            easy to share passwords with others without having to pass the
            passwords back and forth.  It is only necessary to create a shared
            master password in advance. Then new passwords can be created on the
            fly by either party.
        """).strip()
        return text


