# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import argparse

import pytest

from sisl.utils.cmd import *

pytestmark = pytest.mark.utils


def test_default_namespace1():
    d = {'a': 1}
    dd = default_namespace(**d)
    assert dd.a == d['a']


def test_collect_input1():
    argv = ['test.xyz', '--stneohus stnaoeu', '-a', 'aote']
    argv_out, in_file = collect_input(argv)

    assert in_file == 'test.xyz'
    assert len(argv) == len(argv_out) + 1


def test_collect_arguments1():
    ap, ns, argv = collect_arguments([])
    assert len(argv) == 0


def test_collect_arguments2():
    ap, ns, argv = collect_arguments([], input=True)
    assert len(argv) == 0


def test_collect_arguments3():
    with pytest.raises(ValueError):
        collect_arguments(['this.file.never.exists'], input=True)


def test_decorators1():

    # Create a default argument parser
    @default_ArgumentParser('SPBS', description='MY DEFAULT STUFF')
    def myArgParser(self, p=None, *args, **kwargs):
        return p

    p = myArgParser(None)
    assert "SPBS" in p.format_help()
    assert "MY DEFAULT STUFF" in p.format_help()

    p = argparse.ArgumentParser(description='SECOND DEFAULT')
    p = myArgParser(None, p)
    assert "SPBS" not in p.format_help()
    assert "MY DEFAULT STUFF" in p.format_help()
    assert "SECOND DEFAULT" not in p.format_help()


def test_decorators2():

    p = argparse.ArgumentParser()
    ns = default_namespace(my_default='test')

    class Act1(argparse.Action):
        @run_collect_action
        def __call__(self, parser, ns, value, option_string=None):
            setattr(ns, 'act1', value)

    class Act2(argparse.Action):
        @run_collect_action
        def __call__(self, parser, ns, value, option_string=None):
            assert ns.act1 is not None
            setattr(ns, 'act2', value)

    class Act3(argparse.Action):
        @collect_action
        def __call__(self, parser, ns, value, option_string=None):
            setattr(ns, 'act3', value)

    class Act4(argparse.Action):
        def __call__(self, parser, ns, value, option_string=None):
            with pytest.raises(AttributeError):
                assert ns.act3 is None
            setattr(ns, 'act4', value)

    class Act5(argparse.Action):
        @run_actions
        def __call__(self, parser, ns, value, option_string=None):
            pass

    p.add_argument('--a1', action=Act1)
    p.add_argument('--a2', action=Act2)
    p.add_argument('--a3', action=Act3)
    p.add_argument('--a4', action=Act4)
    p.add_argument('--a5', action=Act5, nargs=0)

    # Run arguments
    argv = '--a1 v1 --a2 v2 --a3 v3 --a4 v4'.split()
    args = p.parse_args(argv, namespace=ns)

    assert args.my_default == 'test'

    assert args.act1 == 'v1'
    assert args.act2 == 'v2'
    with pytest.raises(AttributeError):
        assert args.act3 is None
    assert args.act4 == 'v4'

    args = p.parse_args(argv + ['--a5'], namespace=ns)

    assert args.my_default == 'test'

    assert args.act1 == 'v1'
    assert args.act2 == 'v2'
    assert args.act3 == 'v3'
    assert args.act4 == 'v4'
