# test_pamhyr.py -- Pamhyr
# Copyright (C) 2023-2026  INRAE
#
# 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 <https://www.gnu.org/licenses/>.

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

import os
import unittest
import tempfile

from tools import flatten, parse_command_line


class FlattenTestCase(unittest.TestCase):
    def test_flatten_0(self):
        input = []
        output = []

        res = flatten(input)

        self.assertEqual(len(res), len(output))
        for i, o in enumerate(output):
            self.assertEqual(res[i], o)

    def test_flatten_1(self):
        input = [['foo']]
        output = ['foo']

        res = flatten(input)

        self.assertEqual(len(res), len(output))
        for i, o in enumerate(output):
            self.assertEqual(res[i], o)

    def test_flatten_2(self):
        input = [['foo', 'bar']]
        output = ['foo', 'bar']

        res = flatten(input)

        self.assertEqual(len(res), len(output))
        for i, o in enumerate(output):
            self.assertEqual(res[i], o)

    def test_flatten_3(self):
        input = [['foo'], ['bar']]
        output = ['foo', 'bar']

        res = flatten(input)

        self.assertEqual(len(res), len(output))
        for i, o in enumerate(output):
            self.assertEqual(res[i], o)

    def test_flatten_4(self):
        input = [['foo'], ['bar', 'baz'], ['bazz']]
        output = ['foo', 'bar', 'baz', 'bazz']

        res = flatten(input)

        self.assertEqual(len(res), len(output))
        for i, o in enumerate(output):
            self.assertEqual(res[i], o)

    def test_flatten_5(self):
        input = [['foo'], ['bar', ['baz']], ['bazz']]
        output = ['foo', 'bar', ['baz'], 'bazz']

        res = flatten(input)

        self.assertEqual(len(res), len(output))
        for i, o in enumerate(output):
            self.assertEqual(res[i], o)


class ToolsCMDParserTestCase(unittest.TestCase):
    def test_trivial(self):
        cmd = "foo"
        expect = ["foo"]

        res = parse_command_line(cmd)

        self.assertEqual(len(res), len(expect))
        for i, s in enumerate(res):
            self.assertEqual(expect[i], s)

    def test_unix_simple(self):
        cmd = "/foo/bar a -b -c"
        expect = ["/foo/bar", "a", '-b', "-c"]

        res = parse_command_line(cmd)

        self.assertEqual(len(res), len(expect))
        for i, s in enumerate(res):
            self.assertEqual(expect[i], s)

    def test_unix_quoted(self):
        cmd = "\"/foo/bar\" -a -b -c"
        expect = ["/foo/bar", "-a", '-b', "-c"]

        res = parse_command_line(cmd)

        self.assertEqual(len(res), len(expect))
        for i, s in enumerate(res):
            self.assertEqual(expect[i], s)

    def test_unix_quoted_with_space(self):
        cmd = "\"/foo/bar baz\" -a -b -c"
        expect = ["/foo/bar baz", "-a", '-b', "-c"]

        res = parse_command_line(cmd)

        self.assertEqual(len(res), len(expect))
        for i, s in enumerate(res):
            self.assertEqual(expect[i], s)

    def test_unix_quoted_args(self):
        cmd = "/foo/bar -a -b -c=\"baz\""
        expect = ["/foo/bar", "-a", '-b', "-c=\"baz\""]

        res = parse_command_line(cmd)

        self.assertEqual(len(res), len(expect))
        for i, s in enumerate(res):
            self.assertEqual(expect[i], s)

    def test_unix_quoted_args_with_space(self):
        cmd = "/foo/bar -a -b -c=\"baz bazz\""
        expect = ["/foo/bar", "-a", '-b', "-c=\"baz bazz\""]

        res = parse_command_line(cmd)

        self.assertEqual(len(res), len(expect))
        for i, s in enumerate(res):
            self.assertEqual(expect[i], s)

    def test_unix_quoted2_args_with_space(self):
        cmd = "\'/foo/bar baz\' -a -b -c='baz bazz'"
        expect = ["/foo/bar baz", "-a", '-b', "-c='baz bazz'"]

        res = parse_command_line(cmd)

        self.assertEqual(len(res), len(expect))
        for i, s in enumerate(res):
            self.assertEqual(expect[i], s)

    def test_unix_escape_space(self):
        cmd = r"/foo/bar\ baz -a -b -c"
        expect = [r"/foo/bar\ baz", "-a", '-b', "-c"]

        res = parse_command_line(cmd)

        self.assertEqual(len(res), len(expect))
        for i, s in enumerate(res):
            self.assertEqual(expect[i], s)

    def test_windows_prog_files(self):
        cmd = "\"C:\\Program Files (x86)\foo\bar\" a -b -c"
        expect = ["C:\\Program Files (x86)\foo\bar", "a", '-b', "-c"]

        res = parse_command_line(cmd)

        self.assertEqual(len(res), len(expect))
        for i, s in enumerate(res):
            self.assertEqual(expect[i], s)

    def test_windows_prog_files_args(self):
        cmd = "\"C:\\Program Files (x86)\foo\bar\" a -b=\"baz bazz\" -c"
        expect = [
            "C:\\Program Files (x86)\foo\bar",
            "a", '-b=\"baz bazz\"', "-c"
        ]

        res = parse_command_line(cmd)

        self.assertEqual(len(res), len(expect))
        for i, s in enumerate(res):
            self.assertEqual(expect[i], s)

    # Parse must detect malformed command line... But is not :\

    @unittest.expectedFailure
    def test_wrong_format_0(self):
        cmd = "'toto -a -b='baz bazz' -c"
        expect = []

        res = parse_command_line(cmd)

        self.assertEqual(len(res), len(expect))
        for i, s in enumerate(res):
            self.assertEqual(expect[i], s)

    @unittest.expectedFailure
    def test_wrong_format_1(self):
        cmd = "\"toto -a -b=\"baz bazz\" -c"
        expect = []

        res = parse_command_line(cmd)

        self.assertEqual(len(res), len(expect))
        for i, s in enumerate(res):
            self.assertEqual(expect[i], s)

    @unittest.expectedFailure
    def test_wrong_format_2(self):
        cmd = "'toto -a -b=\"baz bazz\" -c"
        expect = []

        res = parse_command_line(cmd)

        self.assertEqual(len(res), len(expect))
        for i, s in enumerate(res):
            self.assertEqual(expect[i], s)
