# -*- coding: utf-8 -*-

from __future__ import print_function
import mock

try:
    # for py26
    import unittest2 as unittest
except ImportError:
    import unittest
try:
    from collections import OrderedDict
except ImportError:
    # for py26
    from ordereddict import OrderedDict

from . import captured_output

from clingon import clingon

# this is to force decorator to delay execution of decorated function
clingon.DELAY_EXECUTION = True

clingon.DEBUG = False

test_version = '0.3.1'

# ---------- here are decorated functions under test -------------
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

@clingon.clize
def clized_default_shorts(p1, p2,
                          first_option='default_value',
                          second_option=5,
                          third_option=[4, 3],
                          last_option=False):
    """Help docstring
    """
    print('%s %s %s %s %s %s' % (p1, p2, first_option, second_option, third_option, last_option))


@clingon.clize(first_option='1', second_option=('2', 's', 'so'))
def clized_spec_shorts(p1, p2,
                       first_option='default_value',
                       second_option=5,
                       third_option=[4, 3],
                       last_option=False):
    if last_option:
        return 12
    print('%s %s %s %s %s %s' % (p1, p2, first_option, second_option, third_option, last_option))


@clingon.clize
def clized_that_raises():
    raise RuntimeError('I just raise')


@clingon.clize
def clized_varargs(p1, p2,
                   option='default_value',
                   *varargs):
    print('%s %s %s %s' % (p1, p2, option, varargs))


def version():
    return '1.2.3'


@clingon.clize
@clingon.set_variables(VERSION=version, message="you can dynamically customize help message !")
def clized_variables(p1, p2, long_name_option='default_value'):
    """Help docstring v{VERSION}
       {message}
    """
    pass


@clingon.clize
@clingon.set_variables(VERSION='1.2.3', message="you can dynamically customize help message !")
def clized_variables_one_short(p1, p2, option='default_value'):
    """Help docstring v{VERSION}
       {message}
    """
    pass

# ---------- end of decorated functions under test --------------
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


class TestDecoratorBasic(unittest.TestCase):
    def test_version(self):
        self.assertEqual(clingon.__version__, test_version)
        import clingon as cli

        self.assertEqual(cli.__version__, test_version)

    def test_decorator_multiple_args(self):
        with self.assertRaises(ValueError) as cm:
            clingon.clize(1, 2)
        message = cm.exception.args[0]
        self.assertEqual(message, "This decorator is for a function only")

    def test_decorator_args_not_function(self):
        with self.assertRaises(ValueError) as cm:
            clingon.clize(1)
        message = cm.exception.args[0]
        self.assertEqual(message, "This decorator is for a function only")

    def test_decorator_kwargs_not_sequence(self):
        with self.assertRaises(ValueError) as cm:
            clingon.clize(toto=1)
        message = cm.exception.args[0]
        self.assertEqual(message, "Decorator's keyword 'toto' value must be "
                                  "a string or a tuple of strings, found: 1")

    def test_kwargs(self):
        def clized(*varargs, **keywargs):
            pass

        with self.assertRaises(TypeError) as cm:
            clingon.clize(clized)
        message = cm.exception.args[0]
        self.assertEqual(message, "Keywords parameter '**keywargs' is not allowed")

    def test_bad_spec_option(self):