package org.jboss.installer.validators;

import org.junit.Assert;
import org.junit.Test;

import javax.swing.JFormattedTextField;
import javax.swing.JTextField;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

public class PortConfigurationValidatorTest {

    public static final String emptyValue = "";
    public static final String validIpAddress = "1.1.1.1";
    public static final String validMaxBitAddress = "255.255.255.255";
    public static final String containsNonNumerical = "a.1.1.1";
    public static final String moreByteAddress = "5.5.5.5.5";
    public static final String lessByteAddress = "3.3.3";
    public static final String not8BitAddress = "300.1.1.1";
    public static final String firstPort = "1111";
    public static final String secondPort = "2222";
    HashMap<String, JTextField> validAddresses = createIpAddressHashmap(Arrays.asList(validIpAddress, validMaxBitAddress));
    HashMap<String, JTextField> invalidAddresses = createIpAddressHashmap(Arrays.asList(validIpAddress, not8BitAddress));
    HashMap<String, JTextField> addressesWithEmptyValue = createIpAddressHashmap(Arrays.asList(emptyValue, validIpAddress));
    HashMap<String, JFormattedTextField> portsWithEmptyValue = createPortFieldHashmap(Arrays.asList(emptyValue, firstPort));
    HashMap<String, JFormattedTextField> distinctPorts = createPortFieldHashmap(Arrays.asList(firstPort, secondPort));
    HashMap<String, JFormattedTextField> notDistinctPorts = createPortFieldHashmap(Arrays.asList(firstPort, secondPort, firstPort));
    private final PortConfigurationValidator validator = new PortConfigurationValidator();

    @Test
    public void isIpAddressFormatTest() {
        Assert.assertTrue(validator.isIpAddressFormat(validIpAddress));
        Assert.assertTrue(validator.isIpAddressFormat(validMaxBitAddress));
        Assert.assertFalse(validator.isIpAddressFormat(containsNonNumerical));
        Assert.assertFalse(validator.isIpAddressFormat(moreByteAddress));
        Assert.assertFalse(validator.isIpAddressFormat(lessByteAddress));
        Assert.assertFalse(validator.isIpAddressFormat(not8BitAddress));
    }

    @Test
    public void isIp6AddressFormatTest() {
        Assert.assertTrue(validator.isIpAddressFormat("2001:db8:3333:4444:5555:6666:7777:8888"));
        Assert.assertTrue(validator.isIpAddressFormat("::"));
        Assert.assertTrue(validator.isIpAddressFormat("2001:db8::1234:5678"));
        Assert.assertTrue(validator.isIpAddressFormat("2001:db8::"));
        Assert.assertFalse(validator.isIpAddressFormat("2001:db8:::"));
        Assert.assertFalse(validator.isIpAddressFormat(""));
        Assert.assertFalse(validator.isIpAddressFormat("GFFF:db8:3333:4444:5555:6666:7777:8888"));
        Assert.assertFalse(validator.isIpAddressFormat("FFFFF:db8:3333:4444:5555:6666:7777:8888"));
        Assert.assertFalse(validator.isIpAddressFormat("-1:db8:3333:4444:5555:6666:7777:8888"));
    }

    @Test
    public void isMulticastFormatTest() {
        Assert.assertFalse(validator.isMulticastAddress("2001:db8:3333:4444:5555:6666:7777:8888"));
        Assert.assertFalse(validator.isMulticastAddress("::"));
        Assert.assertFalse(validator.isMulticastAddress("::1234:5678"));
        Assert.assertTrue(validator.isMulticastAddress("ff02::1"));
        Assert.assertTrue(validator.isMulticastAddress("ff00:db8:3333:4444:5555:6666:7777:8888"));
        Assert.assertTrue(validator.isMulticastAddress("224.0.0.0"));
        Assert.assertTrue(validator.isMulticastAddress("239.255.255.255"));
        Assert.assertFalse(validator.isMulticastAddress("123.1.1.1"));
    }

    @Test
    public void validIpAddressesTest() {
        Assert.assertTrue(validator.validIpAddresses(validAddresses));
        Assert.assertFalse(validator.validIpAddresses(invalidAddresses));
    }

    @Test
    public void valueFieldEmptyTest() {
        Assert.assertFalse(validator.valueFieldEmpty(distinctPorts, validAddresses));
        Assert.assertTrue(validator.valueFieldEmpty(distinctPorts, addressesWithEmptyValue));
        Assert.assertTrue(validator.valueFieldEmpty(portsWithEmptyValue, validAddresses));
        Assert.assertTrue(validator.valueFieldEmpty(portsWithEmptyValue, addressesWithEmptyValue));
    }

    @Test
    public void portsDistinctTest() {
        Assert.assertTrue(validator.portsDistinct(distinctPorts));
        Assert.assertFalse(validator.portsDistinct(notDistinctPorts));
    }

    private HashMap<String, JTextField> createIpAddressHashmap(List<String> addresses) {
        HashMap<String, JTextField> hashMap = new HashMap<>();
        int i = 0;
        for (String address : addresses) {
            hashMap.put(String.valueOf(i++), new JTextField(address));
        }
        return hashMap;
    }

    private HashMap<String, JFormattedTextField> createPortFieldHashmap(List<String> ports) {
        HashMap<String, JFormattedTextField> hashMap = new HashMap<>();
        int i = 0;
        for (String port : ports) {
            hashMap.put(String.valueOf(i++), new JFormattedTextField(port));
        }
        return hashMap;
    }
}
