package de.duehl.basics.logic;

/*
 * Copyright 2020 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import static org.junit.Assert.*;

import java.util.List;

import org.junit.Test;

public class CommandLineArgumentsTest {

    @Test
    public void create1() {
        String[] args = { "foo" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertNotNull(arguments);
    }

    @Test
    public void create2() {
        String[] args = { };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertNotNull(arguments);
    }

    @Test
    public void create3() {
        String[] args = { "--foo" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertNotNull(arguments);
    }

    @Test
    public void getNumberOfParameters01() {
        String[] args = { "--foo", "--bar", "baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertEquals(1, arguments.getNumberOfParameters());
    }

    @Test
    public void getNumberOfParameters02() {
        String[] args = { "--foo", "--bar", "--", "baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertEquals(1, arguments.getNumberOfParameters());
    }

    @Test
    public void getNumberOfParameters03() {
        String[] args = { "--foo", "--", "--bar", "baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertEquals(2, arguments.getNumberOfParameters());
    }

    @Test
    public void getNumberOfFlagOptions01() {
        String[] args = { "--foo", "--bar", "baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertEquals(2, arguments.getNumberOfFlagOptions());
    }

    @Test
    public void getNumberOfFlagOptions02() {
        String[] args = { "--foo", "--bar", "--", "baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertEquals(2, arguments.getNumberOfFlagOptions());
    }

    @Test
    public void getNumberOfFlagOptions03() {
        String[] args = { "--foo", "--", "--bar", "baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertEquals(1, arguments.getNumberOfFlagOptions());
    }

    @Test
    public void getNumberOfValueOptions01() {
        String[] args = { "--foo=eins", "--bar=zwei", "baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertEquals(2, arguments.getNumberOfValueOptions());
    }

    @Test
    public void getNumberOfValueOptions02() {
        String[] args = { "--foo=eins", "--bar=zwei", "--", "baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertEquals(2, arguments.getNumberOfValueOptions());
    }

    @Test
    public void getNumberOfValueOptions03() {
        String[] args = { "--foo=eins", "--", "--bar=zwei", "baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertEquals(1, arguments.getNumberOfValueOptions());
    }

    @Test
    public void getNumberOfMixedFlagAndValueOptions() {
        String[] args = { "--foo", "--baz=brezel", "--bar", "--dasda=sowas", "dings" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertEquals(2, arguments.getNumberOfFlagOptions());
        assertEquals(2, arguments.getNumberOfValueOptions());
    }

    @Test
    public void hasFlagOptions01() {
        String[] args = { "--foo", "--bar", "baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.hasFlagOptions());
        assertTrue(arguments.hasFlagOption("--foo"));
        assertTrue(arguments.hasFlagOption("--bar"));
    }

    @Test
    public void hasFlagOptions02() {
        String[] args = { "--foo", "--bar", "--", "--baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.hasFlagOptions());
        assertTrue(arguments.hasFlagOption("--foo"));
        assertTrue(arguments.hasFlagOption("--bar"));
        assertFalse(arguments.hasFlagOption("--baz"));
    }

    @Test
    public void hasFlagOptions03() {
        String[] args = { "--foo", "--", "--bar", "baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.hasFlagOptions());
        assertTrue(arguments.hasFlagOption("--foo"));
        assertFalse(arguments.hasFlagOption("--bar"));
        assertFalse(arguments.hasFlagOption("baz"));
    }

    @Test
    public void hasValueOptions01() {
        String[] args = { "--foo=eins", "--bar=zwei", "baz=drei" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.hasValueOptions());
        assertTrue(arguments.hasValueOption("--foo"));
        assertTrue(arguments.hasValueOption("--bar"));
    }

    @Test
    public void hasValueOptions02() {
        String[] args = { "--foo=eins", "--bar=zwei", "--", "--baz=drei" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.hasValueOptions());
        assertTrue(arguments.hasValueOption("--foo"));
        assertTrue(arguments.hasValueOption("--bar"));
        assertFalse(arguments.hasValueOption("--baz"));
    }

    @Test
    public void hasValueOptions03() {
        String[] args = { "--foo=eins", "--", "--bar=zwei", "baz=drei" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.hasValueOptions());
        assertTrue(arguments.hasValueOption("--foo"));
        assertFalse(arguments.hasValueOption("--bar"));
        assertFalse(arguments.hasValueOption("baz"));
    }

    @Test
    public void getParameter01() {
        String[] args = { "--foo", "--", "--bar", "baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        String bar = arguments.getParameter(0);
        String baz = arguments.getParameter(1);
        assertEquals("--bar", bar);
        assertEquals("baz", baz);
    }

    @Test
    public void getParameter02() {
        String[] args = { "--foo", "--bar", "baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        String baz = arguments.getParameter(0);
        assertEquals("baz", baz);
    }

    @Test
    public void hasNoParameter() {
        String[] args = { };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.haveNoParameters());
    }

    @Test
    public void hasNoParameter2() {
        String[] args = { "--huhu" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.haveNoParameters());
    }

    @Test
    public void hasNoFlagOptions() {
        String[] args = { };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.haveNoFlagOptions());
    }

    @Test
    public void hasNoFlagOptions2() {
        String[] args = { "foo" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.haveNoFlagOptions());
    }

    @Test
    public void hasNoFlagOptions3() {
        String[] args = { "--dings=sowas", "foo" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.haveNoFlagOptions());
    }

    @Test
    public void hasNoValueOptions() {
        String[] args = { };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.haveNoValueOptions());
    }

    @Test
    public void hasNoValueOptions2() {
        String[] args = { "foo" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.haveNoValueOptions());
    }

    @Test
    public void hasNoValueOptions3() {
        String[] args = { "--dings", "foo" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.haveNoValueOptions());
    }

    @Test
    public void getParameter() {
        String[] args = { "eins" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertFalse(arguments.haveNoParameters());
        assertTrue(arguments.haveNoFlagOptions());
        assertTrue(arguments.numberOfParameterIs(1));
        assertEquals("eins", arguments.getParameter(0));
    }

    @Test
    public void hasHelpOption1() {
        String[] args = { "--help" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.haveHelpOption());
    }

    @Test
    public void hasHelpOption2() {
        String[] args = { "-h" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.haveHelpOption());
    }

    @Test
    public void hasHelpOption3() {
        String[] args = { "/?" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertTrue(arguments.haveHelpOption());
    }

    @Test
    public void hasHelpOptionFails() {
        String[] args = { "--keine", "help-Option", "vorhanden" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        assertFalse(arguments.haveHelpOption());
    }

    @Test
    public void toStringTest() {
        String[] args = { "--option_eins", "parameter_0", "--option_zwei", "parameter_1" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        String actual = arguments.toString();
        String expected = "    Optionen ohne zugeordnete Werte:\n"
            + "        --option_eins\n"
            + "        --option_zwei\n"
            + "    Optionen mit zugeordneten Werten:\n"
            + "    Parameter:\n"
            + "        0) parameter_0\n"
            + "        1) parameter_1\n";
        assertEquals(expected, actual);
    }

    @Test
    public void toStringTestWithValueOptions() {
        String[] args = { "--option_eins", "parameter_0", "--option_zwei", "--foo=bar",
                "parameter_1" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        String actual = arguments.toString();
        String expected = "    Optionen ohne zugeordnete Werte:\n"
            + "        --option_eins\n"
            + "        --option_zwei\n"
            + "    Optionen mit zugeordneten Werten:\n"
            + "        --foo = bar\n"
            + "    Parameter:\n"
            + "        0) parameter_0\n"
            + "        1) parameter_1\n";
        assertEquals(expected, actual);
    }

    @Test
    public void getCommandLineEmpty() {
        String[] args = {  };
        CommandLineArguments arguments = new CommandLineArguments(args);
        String actual = arguments.getCommandLine();
        String expected = "";
        assertEquals(expected, actual);
    }

    @Test
    public void getCommandLine() {
        String[] args = { "--option_eins", "parameter_0", "--option_zwei", "parameter_1" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        String actual = arguments.getCommandLine();
        String expected = "--option_eins parameter_0 --option_zwei parameter_1";
        assertEquals(expected, actual);
    }

    @Test
    public void getCommandLineWithValueOption() {
        String[] args = { "--option_eins", "parameter_0", "--option_zwei", "--foo=bar",
                "parameter_1" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        String actual = arguments.getCommandLine();
        String expected = "--option_eins parameter_0 --option_zwei --foo=bar parameter_1";
        assertEquals(expected, actual);
    }

    @Test
    public void getParametersFromEmptyList() {
        String[] args = {  };
        CommandLineArguments arguments = new CommandLineArguments(args);
        List<String> params = arguments.getParameters();
        assertEquals(0, params.size());
    }

    @Test
    public void getParametersWithoutNormalParameters() {
        String[] args = { "--dings", "--foo=bar" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        List<String> params = arguments.getParameters();
        assertEquals(0, params.size());
    }

    @Test
    public void getParametersBetweenOthers() {
        String[] args = { "--dings", "foo", "--dings2", "--foo=bar" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        List<String> params = arguments.getParameters();
        assertEquals(1, params.size());
        assertEquals("foo", params.get(0));
    }

    @Test
    public void getParametersAfterOthers() {
        String[] args = { "--dings", "foo" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        List<String> params = arguments.getParameters();
        assertEquals(1, params.size());
        assertEquals("foo", params.get(0));
    }

    @Test
    public void getParametersBeforeOthers() {
        String[] args = { "foo", "--dings" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        List<String> params = arguments.getParameters();
        assertEquals(1, params.size());
        assertEquals("foo", params.get(0));
    }

    @Test
    public void getMultipleParameters() {
        String[] args = { "--dings", "foo", "--dings2", "--foo=bar", "bar", "--glubsch", "baz" };
        CommandLineArguments arguments = new CommandLineArguments(args);
        List<String> params = arguments.getParameters();
        assertEquals(3, params.size());
        assertEquals("foo", params.get(0));
        assertEquals("bar", params.get(1));
        assertEquals("baz", params.get(2));
    }

}
