package de.duehl.basics.version;

/*
 * Copyright 2024 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 VersionTest {

    @Test
    public void create() {
        Version version = new Version("", "");
        assertTrue(null != version);
    }

    @Test
    public void getVersion() {
        String expected = "0.0.1";
        Version version = new Version(expected, "");
        String result = version.getVersion();
        assertEquals(expected, result);
    }

    @Test
    public void getDate() {
        String expected = "01.02.2001";
        Version version = new Version("", expected);
        String result = version.getDate();
        assertEquals(expected, result);
    }

    @Test
    public void getVersionAndDate() {
        Version version = new Version("0.0.1", "01.02.2017");
        String actual = version.getVersionAndDate();
        String expected = "0.0.1 vom 01.02.2017";
        assertEquals(expected, actual);
    }

    @Test
    public void toString1() {
        Version version = new Version("17.3", "23.02.2012");
        String expected = "Version 17.3 vom 23.02.2012";
        String result = version.toString();
        assertEquals(expected, result);
    }

    @Test
    public void numerical1() {
        Version version = new Version("17.3", "01.08.2013");
        List<Integer> numerical = version.getNumericVersion();
        assertEquals(2, numerical.size());
    }

    @Test
    public void numerical2() {
        Version version = new Version("17.3", "01.08.2013");
        List<Integer> numerical = version.getNumericVersion();
        assertEquals(2, numerical.size());
        int i1 = numerical.get(0);
        int i2 = numerical.get(1);
        assertEquals(17, i1);
        assertEquals( 3, i2);
    }

    @Test
    public void numerical3() {
        Version version = new Version("0.17.3", "01.08.2013");
        List<Integer> numerical = version.getNumericVersion();
        assertEquals(3, numerical.size());
        int i1 = numerical.get(0);
        int i2 = numerical.get(1);
        int i3 = numerical.get(2);
        assertEquals( 0, i1);
        assertEquals(17, i2);
        assertEquals( 3, i3);
    }

    @Test
    public void numerical4() {
        Version version = new Version("0.17.3a", "01.08.2013");
        List<Integer> numerical = version.getNumericVersion();
        assertEquals(4, numerical.size());
        int i1 = numerical.get(0);
        int i2 = numerical.get(1);
        int i3 = numerical.get(2);
        int i4 = numerical.get(3);
        assertEquals(  0, i1);
        assertEquals( 17, i2);
        assertEquals(  3, i3);
        assertEquals( 97, i4);
        assertEquals('a', i4);
    }

    @Test
    public void numerical5() {
        Version version = new Version("0.17.3_a", "01.08.2013");
        List<Integer> numerical = version.getNumericVersion();
        assertEquals(4, numerical.size());
        int i1 = numerical.get(0);
        int i2 = numerical.get(1);
        int i3 = numerical.get(2);
        int i4 = numerical.get(3);
        assertEquals(  0, i1);
        assertEquals( 17, i2);
        assertEquals(  3, i3);
        assertEquals( 97, i4);
        assertEquals('a', i4);
    }

    @Test
    public void numerical6() {
        Version version = new Version("0a17.#§$%3_d:::bc8", "01.08.2013");
        List<Integer> numerical = version.getNumericVersion();
        assertEquals(8, numerical.size());
        int i1 = numerical.get(0);
        int i2 = numerical.get(1);
        int i3 = numerical.get(2);
        int i4 = numerical.get(3);
        int i5 = numerical.get(4);
        int i6 = numerical.get(5);
        int i7 = numerical.get(6);
        int i8 = numerical.get(7);
        assertEquals(  0, i1);
        assertEquals( 97, i2);
        assertEquals('a', i2);
        assertEquals( 17, i3);
        assertEquals(  3, i4);
        assertEquals(100, i5);
        assertEquals('d', i5);
        assertEquals( 98, i6);
        assertEquals('b', i6);
        assertEquals( 99, i7);
        assertEquals('c', i7);
        assertEquals(  8, i8);
    }

    @Test
    public void compareTo1() {
        Version version1 = new Version("0a17.#§$%3_d:::bc8", "01.08.2013");
        Version version2 = new Version("0a.17.3_dbc.8", "01.08.2013");
        assertEquals(0, version1.compareTo(version2));
    }

    @Test
    public void compareTo2() {
        Version version1 = new Version("0.17.3a", "01.08.2013");
        Version version2 = new Version("0.17.3_a", "01.08.2013");
        assertEquals(0, version1.compareTo(version2));
    }

    @Test
    public void compareTo3() {
        Version version1 = new Version("0.2.49", "Dezember 2020");
        Version version2 = new Version("0.2.49a", "Januar 2021");
        assertEquals(-1, version1.compareTo(version2));
    }

    @Test
    public void equals1() {
        Version version1 = new Version("0a17.#§$%3_d:::bc8", "01.08.2013");
        Version version2 = new Version("0a.17.3_dbc.8", "01.08.2013");
        assertEquals(version1, version2);
    }

    @Test
    public void equals2() {
        Version version1 = new Version("0.17.3a", "01.08.2013");
        Version version2 = new Version("0.17.3_a", "01.08.2013");
        assertEquals(version1, version2);
    }

    @Test
    public void equals3() {
        Version version1 = new Version("0.17.3a", "01.08.2013");
        Version version2 = new Version("0.17.3.97", "01.08.2013");
        assertEquals(version1, version2);
    }

    @Test
    public void hashcode1() {
        Version version1 = new Version("0a17.#§$%3_d:::bc8", "01.08.2013");
        Version version2 = new Version("0a.17.3_dbc.8", "01.08.2013");
        assertEquals(version1.hashCode(), version2.hashCode());
    }

    @Test
    public void hashcode2() {
        Version version1 = new Version("0.17.3a", "01.08.2013");
        Version version2 = new Version("0.17.3_a", "01.08.2013");
        assertEquals(version1.hashCode(), version2.hashCode());
    }

    @Test
    public void getYear() {
        Version version = new Version("0.0.01", "August 2019");
        assertEquals("2019", version.getYear());
    }

    @Test
    public void toSerializeString() {
        Version version = new Version("0.0.01", "Dezember 2020");
        String actual = version.toSerializedString();
        String expected = "0.0.01" + "#;#" + "Dezember 2020";
        assertEquals(expected, actual);
    }

    @Test
    public void createFromSerealizedString() {
        String serialized = "0.0.01" + "#;#" + "Dezember 2020";
        Version actual = Version.createFromSerializedString(serialized);
        Version expected = new Version("0.0.01", "Dezember 2020");
        assertEquals(expected, actual);
    }

    @Test
    public void extractVersionFromJarFilename() {
        String jarName = "c:\\Users\\setup\\Daten\\Sonstiges\\Vokabel-Trainer-Test\\"
                + "de.duehl.vocabulary.japanese_0.03.02.jar";
        String jarNameStart = "de.duehl.vocabulary.japanese_";
        String actual = Version.extractVersionFromJarFilename(jarName, jarNameStart);
        String expected = "0.03.02";
        assertEquals(expected , actual);
    }

    @Test
    public void isNewerThanEqualVersions() {
        Version version1 = new Version("0.0.01", "Dezember 2024");
        Version version2 = new Version("0.0.01", "Dezember 2024");
        assertFalse(version1.isNewerThan(version2));
    }

    @Test
    public void isNewerThanEqualVersionsWithoutZero1() {
        Version version1 = new Version("0.0.01", "Dezember 2024");
        Version version2 = new Version("0.0.1", "Dezember 2024");
        assertFalse(version1.isNewerThan(version2));
    }

    @Test
    public void isNewerThanEqualVersionsWithoutZero2() {
        Version version1 = new Version("0.0.1", "Dezember 2024");
        Version version2 = new Version("0.0.01", "Dezember 2024");
        assertFalse(version1.isNewerThan(version2));
    }

    @Test
    public void isNewerThanEqualVersionsHigherLowNumber1() {
        Version version1 = new Version("0.0.02", "Dezember 2024");
        Version version2 = new Version("0.0.01", "Dezember 2024");
        assertTrue(version1.isNewerThan(version2));
    }

    @Test
    public void isNewerThanEqualVersionsHigherLowNumber2() {
        Version version1 = new Version("0.0.01", "Dezember 2024");
        Version version2 = new Version("0.0.02", "Dezember 2024");
        assertFalse(version1.isNewerThan(version2));
    }

    @Test
    public void isNewerThanEqualVersionsHigherMiddleNumber1() {
        Version version1 = new Version("0.02.01", "Dezember 2024");
        Version version2 = new Version("0.01.01", "Dezember 2024");
        assertTrue(version1.isNewerThan(version2));
    }

    @Test
    public void isNewerThanEqualVersionsHigherMiddleNumber2() {
        Version version1 = new Version("0.01.01", "Dezember 2024");
        Version version2 = new Version("0.02.01", "Dezember 2024");
        assertFalse(version1.isNewerThan(version2));
    }

    @Test
    public void isNewerThanEqualVersionsHigherHighNumber1() {
        Version version1 = new Version("02.01.01", "Dezember 2024");
        Version version2 = new Version("01.01.01", "Dezember 2024");
        assertTrue(version1.isNewerThan(version2));
    }

    @Test
    public void isNewerThanEqualVersionsHigherHighNumber2() {
        Version version1 = new Version("01.01.01", "Dezember 2024");
        Version version2 = new Version("02.01.01", "Dezember 2024");
        assertFalse(version1.isNewerThan(version2));
    }

    @Test
    public void isNewerThanEqualVersionsHigherCharacterAtEnd1AgainstNoCharacter() {
        Version version1 = new Version("00.00.01a", "Dezember 2024");
        Version version2 = new Version("00.00.01", "Dezember 2024");
        assertTrue(version1.isNewerThan(version2));
    }

    @Test
    public void isNewerThanEqualVersionsHigherCharacterAtEnd2AgainstNoCharacter() {
        Version version1 = new Version("00.00.01", "Dezember 2024");
        Version version2 = new Version("00.00.01a", "Dezember 2024");
        assertFalse(version1.isNewerThan(version2));
    }

    @Test
    public void isNewerThanEqualVersionsHigherCharacterAtEnd1AgainstOtherCharacter() {
        Version version1 = new Version("00.00.01b", "Dezember 2024");
        Version version2 = new Version("00.00.01a", "Dezember 2024");
        assertTrue(version1.isNewerThan(version2));
    }

    @Test
    public void isNewerThanEqualVersionsHigherCharacterAtEnd2AgainstOtherCharacter() {
        Version version1 = new Version("00.00.01a", "Dezember 2024");
        Version version2 = new Version("00.00.01b", "Dezember 2024");
        assertFalse(version1.isNewerThan(version2));
    }

}
