package com.knecon.fforesight.service.layoutparser.server.graph;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.Collections;
import java.util.List;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.knecon.fforesight.service.layoutparser.processor.model.graph.Boundary;

class BoundaryTest {

    Boundary startBoundary;


    @BeforeEach
    void setUp() {

        startBoundary = new Boundary(10, 100);
    }


    @Test
    void testContains() {

        assertTrue(startBoundary.contains(11));
        assertTrue(startBoundary.contains(50));
        assertFalse(startBoundary.contains(9));
        assertFalse(startBoundary.contains(100));
        assertFalse(startBoundary.contains(150));
        assertFalse(startBoundary.contains(-123));
        assertTrue(startBoundary.contains(new Boundary(11, 99)));
        assertTrue(startBoundary.contains(new Boundary(10, 100)));
        assertTrue(startBoundary.contains(new Boundary(11, 11)));
        assertFalse(startBoundary.contains(9, 100));
        assertTrue(startBoundary.contains(100, 100));
        assertFalse(startBoundary.contains(100, 101));
        assertFalse(startBoundary.contains(150, 151));
    }


    @Test
    void testIntersects() {

        assertTrue(startBoundary.intersects(new Boundary(1, 11)));
        assertTrue(startBoundary.intersects(new Boundary(11, 12)));
        assertTrue(startBoundary.intersects(new Boundary(11, 100)));
        assertFalse(startBoundary.intersects(new Boundary(100, 101)));
        assertTrue(startBoundary.intersects(new Boundary(99, 101)));
    }


    @Test
    void testSplit() {

        assertEquals(4, startBoundary.split(List.of(12, 40, 90)).size());
        assertEquals(List.of(new Boundary(10, 12), new Boundary(12, 40), new Boundary(40, 90), new Boundary(90, 100)), startBoundary.split(List.of(12, 40, 90)));
        assertEquals(List.of(new Boundary(10, 40), new Boundary(40, 100)), startBoundary.split(List.of(40)));
        assertEquals(1, startBoundary.split(Collections.emptyList()).size());
        assertEquals(1, startBoundary.split(List.of(startBoundary.start())).size());
        assertThrows(IndexOutOfBoundsException.class, () -> startBoundary.split(Collections.singletonList(0)));
        assertThrows(IndexOutOfBoundsException.class, () -> startBoundary.split(Collections.singletonList(100)));
        assertThrows(IndexOutOfBoundsException.class, () -> startBoundary.split(List.of(12, 40, 100)));
    }

}