#! /usr/bin/env python2
# -*- coding: utf-8 -*-
# PYTHON_ARGCOMPLETE_OK

# This file is part of Linshare user cli.
#
# LinShare user cli 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.
#
# LinShare user cli 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 LinShare user cli.  If not, see <http://www.gnu.org/licenses/>.
#
# Copyright 2013 Frédéric MARTIN
#
# Contributors list :
#
#  Frédéric MARTIN frederic.martin.fma@gmail.com
#

# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------
from __future__ import unicode_literals

import os
import sys
import argparse
import logging
import logging.handlers
import codecs
import locale

from argtoolbox import BasicProgram
from argtoolbox import SimpleSection
from argtoolbox import Element
from argtoolbox import streamHandler
from argtoolbox import DEBUG_LOGGING_FORMAT
from argtoolbox import Base64ElementHook
from argtoolbox import SectionHook
from linshare_cli.user import add_document_parser
from linshare_cli.user import add_share_parser
from linshare_cli.user import add_received_share_parser
from linshare_cli.user import add_threads_parser
from linshare_cli.user import add_users_parser
from linshare_cli.user import add_test_parser
import linshare_cli

# if you want to debug argcomplete completion,
# you just need to export _ARC_DEBUG=True


sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)
# Not use full ?
#sys.stdin = codecs.getreader(locale.getpreferredencoding())(sys.stdin)


# -----------------------------------------------------------------------------
class LinShareCliProgram(BasicProgram):
    """Main program."""

    def add_config_options(self):
        self.formatter_class = argparse.RawTextHelpFormatter

        section_server = self.config.add_section(SimpleSection("server"))

        section_server.add_element(Element(
            'host',
            required=True))

        section_server.add_element(Element(
            'realm',
            desc=argparse.SUPPRESS,
            default="Name Of Your LinShare Realm"))

        section_server.add_element(Element('user', required=True))

        section_server.add_element(Element(
            'password',
            hidden=True,
            desc="user password to linshare",
            hooks=[Base64ElementHook(warning=True), ]))

        section_server.add_element(Element(
            'application_name',
            default="linshare",
            conf_hidden=True,
            desc="Default value is 'linshare' (ex: http:/x.x.x.x/linshare)"))

        section_server.add_element(Element(
            'nocache',
            e_type=bool,
            default=False,
            desc=argparse.SUPPRESS))

        section_server.add_element(Element('verbose'))

        section_server.add_element(Element(
            'debug',
            e_type=int,
            default=0,
            desc="""(default: 0)
0 : debug off
1 : debug on
2 : debug on and request result is printed (pretty json)
3 : debug on and urllib debug on and http headers and request
are printed"""
        ))

    def add_pre_commands(self):

        self.parser.add_argument(
            '-s',
            action="store",
            dest='server_section',
            help="""This option let you select the server section in the cfg
file you want to load (server section is always load first as default
configuration). You just need to specify a number like '4' for
section 'server-4'""")

        self.parser.add_argument(
            '-d',
            action="count",
            **self.config.server.debug.get_arg_parse_arguments())

    def reload(self):
        # If section_server is defined, we need to modify the suffix
        # attribute ofserver Section object.
        hook = SectionHook(self.config.server, "_suffix", "server_section")

        # Reloading configuration with previous optional arguments
        # (ex config file name, server section, ...)
        self.config.reload(hook)

    def add_commands(self):

        # Adding all others options.
        self.parser.add_argument(
            '-u',
            '--user',
            action="store",
            **self.config.server.user.get_arg_parse_arguments())

        password_group = self.parser.add_argument_group('Password')
        password_required = True
        if self.config.server.password is not None:
            password_required = False
        group = password_group.add_mutually_exclusive_group(
            required=password_required)
        group.add_argument(
            '-P',
            '--password',
            action="store",
            **self.config.server.password.get_arg_parse_arguments())

        group.add_argument(
            '-p',
            action="store_true",
            default=False,
            dest="ask_password",
            help="If set, the program will ask you your password.")

        self.parser.add_argument(
            '-H',
            '--host',
            action="store",
            **self.config.server.host.get_arg_parse_arguments())

        self.parser.add_argument(
            '-r',
            '--realm',
            action="store",
            **self.config.server.realm.get_arg_parse_arguments())

        self.parser.add_argument(
            '--nocache',
            action="store_true",
            **self.config.server.nocache.get_arg_parse_arguments())

        self.parser.add_argument(
            '-a',
            '--appname',
            action="store",
            **self.config.server.application_name.get_arg_parse_arguments())

        # Adding all others parsers.
        subparsers = self.parser.add_subparsers()
        add_document_parser(subparsers, "documents", "Documents management")
        add_threads_parser(subparsers, "threads", "threads management")
        add_share_parser(subparsers, "shares", "Created shares management")
        add_received_share_parser(subparsers,
                                  "received_shares",
                                  "Received shares management")
        add_received_share_parser(subparsers,
                                  "rshares",
                                  "Alias of received_share command")
        add_users_parser(subparsers, "users", "users")
        add_test_parser(subparsers, self.config)


PROG = LinShareCliProgram(
    "linshare-cli",
    version=linshare_cli.__version__,
    force_debug = os.getenv('_LINSHARE_CLI_USER_DEBUG', False),
    force_debug_to_file = os.getenv('_LINSHARE_CLI_USER_DEBUG_FILE', False),
    desc="""An user cli for LinShare, using its REST API.


Advanced documentation :
------------------------
If you need debug during class construction, config file loading,
you just need to export _LINSHARE_CLI_USER_DEBUG=True

================================================================
""")
if __name__ == "__main__":
    PROG()
