#! /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 codecs
import locale

from argtoolbox import BasicProgram
from argtoolbox import SimpleSection
from argtoolbox import Element
from argtoolbox import Base64ElementHook
from argtoolbox import SectionHook
from linsharecli.user.document import add_parser as add_document_parser
from linsharecli.user.share import add_parser as add_share_parser
from linsharecli.user.rshare import add_parser as add_received_share_parser
from linsharecli.user.thread import add_parser as add_threads_parser
from linsharecli.user.tmember import add_parser as add_tmembers_parser
from linsharecli.user.tdocuments import add_parser as add_tdocuments_parser
from linsharecli.user.user import add_parser as add_users_parser
from linsharecli.user.core import add_parser as add_core_parser
import linsharecli

# 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(
            'api_version',
            default=int(os.getenv('LS_API', 1)),
            e_type=int,
            desc="""The linshare api version to be used. Default '1'.
* For LinShare Core = 1.7.x, use api_version=0.
* For LinShare Core >= 1.8.x, use api_version=1.
The default value can be overriden by the env variable LS_API, which can be
overriden by this parameter."""))

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

        section_server.add_element(Element(
            'password',
            hidden=True,
            desc="user password to linshare. See cli help for using env variable instead.",
            hooks=[Base64ElementHook(warning=True), ]))

        section_server.add_element(Element(
            'base_url',
            desc="Default value is 'linshare/webservice/rest'"))

        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,
            e_type_exclude=True,
            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.")

        group.add_argument(
            '-E',
            action="store_true",
            default=False,
            dest="env_password",
            help="If set, the program will load your password from LS_PASSWORD environement variable.")

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

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

        self.parser.add_argument(
            '--base-url',
            action="store",
            **self.config.server.base_url.get_arg_parse_arguments())

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


PROG = LinShareCliProgram(
    "linshare-cli",
    version=linsharecli.__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.

    In order to enable auto complete support, or generate the default
    configuration file associated with the current program,
    look at the argtoolboxtool program : `argtoolboxtool generate  linsharecli`


Advanced documentation :
========================

API Version :
-------------

    This client support multiple LinShare server and its API version.
The default value '1' can be overriden by the env variable LS_API, which can be
set in the configuration file.
* For LinShare Core = 1.7.x, use api_version=0.
* For LinShare Core >= 1.8.x, use api_version=1.

Advanced debug:
---------------

* If you need debug during class construction, config file loading,
you just need to export _LINSHARE_CLI_USER_DEBUG=True
* To debug auto completion, you need to export _ARC_DEBUG=1.

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