package ru.kirillius.pf.sdn.core.Networking;

import org.junit.jupiter.api.Test;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

class IPv4SubnetTest {
    @SuppressWarnings("CatchMayIgnoreException")
    @Test
    void testInit() {
        var validPrefixes = List.of(0, 5, 20, 32);
        var invalidPrefixes = List.of(-1, 33, 800);
        var validAddresses = List.of("1.2.3.4", "0.0.0.0", "255.255.255.255");
        var invalidAddresses = List.of("1", "0.0.0", "255.255.255.255.255", "1.2.3.256", "-1.0.0.0");


        validPrefixes.forEach(prefix -> {
            validAddresses.forEach(address -> {
                var subnet = new IPv4Subnet(address, prefix);
            });
        });

        invalidPrefixes.forEach(prefix -> {
            validAddresses.forEach(address -> {
                try {
                    var subnet = new IPv4Subnet(address, prefix);
                    throw new AssertionError();
                } catch (Throwable e) {
                    assertThat(e).isInstanceOf(IllegalArgumentException.class);
                }
            });
        });

        validPrefixes.forEach(prefix -> {
            invalidAddresses.forEach(address -> {
                try {
                    var subnet = new IPv4Subnet(address, prefix);
                    throw new AssertionError();
                } catch (Throwable e) {
                    assertThat(e).isInstanceOf(IllegalArgumentException.class);
                }
            });
        });

        invalidPrefixes.forEach(prefix -> {
            invalidAddresses.forEach(address -> {
                try {
                    var subnet = new IPv4Subnet(address, prefix);
                    throw new AssertionError();
                } catch (Throwable e) {
                    assertThat(e).isInstanceOf(IllegalArgumentException.class);
                }
            });
        });

    }

    @Test
    void overlaps() {
        checkOverlaps(
                new IPv4Subnet("0.0.0.0", 0),
                new IPv4Subnet("8.8.8.8", 32)
        );

        checkOverlaps(
                new IPv4Subnet("192.168.0.0", 24),
                new IPv4Subnet("192.168.0.128", 25)
        );
    }

    private void checkOverlaps(IPv4Subnet larger, IPv4Subnet smaller) {
        assertThat(larger.overlaps(smaller)).isTrue();
        assertThat(smaller.overlaps(larger)).isFalse();
    }
}