package de.duehl.basics.collections;

/*
 * Copyright 2018 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 org.junit.Test;

import de.duehl.basics.collections.data.KeyAndValue;

public class OrderedStringKeyMapTest {

    @SuppressWarnings("deprecation")
    @Test
    public void emptySizeAfterCreate() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        int actual = map.size();
        int expected = 0;
        assertEquals(expected, actual);
    }

    @SuppressWarnings("deprecation")
    @Test
    public void sizeAfterAddingAFewElementsCreate() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        map.put("eins", 1);
        map.put("zwei", 2);
        map.put("drei", 1);
        map.put("vier", 4);
        int actual = map.size();
        int expected = 4;
        assertEquals(expected, actual);
    }

    @SuppressWarnings("deprecation")
    @Test (expected = IllegalArgumentException.class)
    public void addingTwoIdenticalKeys() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        map.put("eins", 1);
        map.put("eins", 2);
    }

    @SuppressWarnings("deprecation")
    @Test
    public void isEmptyAfterCreate() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        assertTrue(map.isEmpty());
    }

    @SuppressWarnings("deprecation")
    @Test
    public void isNotEmptyAfterAddingAFewElementsCreate() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        map.put("eins", 1);
        map.put("zwei", 2);
        map.put("drei", 1);
        map.put("vier", 4);
        assertFalse(map.isEmpty());
    }

    @SuppressWarnings("deprecation")
    @Test
    public void containsKeyAfterCreate() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        assertFalse(map.containsKey("eins"));
    }

    @SuppressWarnings("deprecation")
    @Test
    public void containsKeyAfterAddingAFewElementsCreate() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        map.put("eins", 1);
        map.put("zwei", 2);
        map.put("drei", 1);
        map.put("vier", 4);
        assertTrue(map.containsKey("eins"));
        assertTrue(map.containsKey("zwei"));
        assertTrue(map.containsKey("drei"));
        assertTrue(map.containsKey("vier"));
        assertFalse(map.containsKey("fünf"));
    }

    @SuppressWarnings("deprecation")
    @Test
    public void containsValueAfterCreate() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        assertFalse(map.containsValue(1));
    }

    @SuppressWarnings("deprecation")
    @Test
    public void containsValueAfterAddingAFewElementsCreate() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        map.put("eins", 1);
        map.put("zwei", 2);
        map.put("drei", 1);
        map.put("vier", 4);
        assertTrue(map.containsValue(1));
        assertTrue(map.containsValue(2));
        assertFalse(map.containsValue(3));
        assertTrue(map.containsValue(4));
        assertFalse(map.containsValue(5));
    }

    @SuppressWarnings("deprecation")
    @Test (expected = IllegalArgumentException.class)
    public void getAfterCreate() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        map.get("eins");
    }

    @SuppressWarnings("deprecation")
    @Test
    public void getAfterAddingAFewElementsCreate() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        map.put("eins", 1);
        map.put("zwei", 2);
        map.put("drei", 1);
        map.put("vier", 4);
        assertEquals(Integer.valueOf(1), map.get("eins"));
        assertEquals(Integer.valueOf(2), map.get("zwei"));
        assertEquals(Integer.valueOf(1), map.get("drei"));
        assertEquals(Integer.valueOf(4), map.get("vier"));
    }

    @SuppressWarnings("deprecation")
    @Test (expected = IllegalArgumentException.class)
    public void removeAfterCreate() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        map.remove("eins");
    }

    @SuppressWarnings("deprecation")
    @Test
    public void removeAfterAddingAFewElementsCreate() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        map.put("eins", 1);
        map.put("zwei", 2);
        map.put("drei", 1);
        map.put("vier", 4);
        assertEquals(Integer.valueOf(1), map.remove("eins"));
        assertEquals(Integer.valueOf(2), map.remove("zwei"));
        assertEquals(Integer.valueOf(1), map.remove("drei"));
        assertEquals(Integer.valueOf(4), map.remove("vier"));
        assertTrue(map.isEmpty());
    }

    @SuppressWarnings("deprecation")
    @Test
    public void clearAfterAddingAFewElementsCreate() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        map.put("eins", 1);
        map.put("zwei", 2);
        map.put("drei", 1);
        map.put("vier", 4);
        map.clear();
        assertTrue(map.isEmpty());
    }

    @SuppressWarnings("deprecation")
    @Test
    public void iterate() {
        OrderedStringKeyMap<Integer> map = new OrderedStringKeyMap<>();
        map.put("eins", 1);
        map.put("zwei", 2);
        map.put("drei", 1);
        map.put("vier", 4);

        int index = 0;
        for (KeyAndValue<Integer> keyAndValue : map) {
            //System.out.println(index + " -> " + keyAndValue);
            String key = keyAndValue.getKey();
            int value = keyAndValue.getValue();
            //System.out.println(index + " -> key = " + key + ", value = " + value);
            if (0 == index) {
                assertEquals("eins", key);
                assertEquals(1, value);
            }
            else if (1 == index) {
                assertEquals("zwei", key);
                assertEquals(2, value);
            }
            else if (2 == index) {
                assertEquals("drei", key);
                assertEquals(1, value);
            }
            else if (3 == index) {
                assertEquals("vier", key);
                assertEquals(4, value);
            }
            ++index;
        }
    }

}
