package school_project.Parsers;

import org.junit.jupiter.api.*;
import org.junit.jupiter.api.io.TempDir;
import school_project.Map;
import school_project.Piece;
import school_project.Vec2;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;

import static org.junit.jupiter.api.Assertions.*;

class FileParserFactoryTest {

    static Map generateMapTest(){
        boolean[][] map_shape = {
                {false, false, true, true, false, false},
                {false, true, true, true, true, false},
                {true, true, false, false, true, true},
                {true, true, false, false, true, true},
                {true, true, true, true, true, true},
        };
        boolean[][] piece1_shape = {
                {false, true},
                {true, true},
        };
        boolean[][] piece2_shape = {
                {true, false, false},
                {true, true, false},
                {false, true, true},
        };
        boolean[][] piece3_shape = {
                {false, true, true},
                {true, true, true},
        };
        boolean[][] piece4_shape = {
                {true, true, false},
                {true, true, false},
                {true, true, true},
        };
        Piece[] pieces = { new Piece(piece1_shape), new Piece(piece2_shape), new Piece(piece3_shape), new Piece(piece4_shape) };
        Map map = new Map(map_shape);
        map.addPiece(pieces);

        pieces[0].setPosition(new Vec2(1, 0));
        pieces[1].setPosition(new Vec2(3, 0));
        pieces[2].setPosition(new Vec2(3, 3));
        pieces[3].setPosition(new Vec2(0, 2));
        return map;
    }

    @Test
    void saveLoadFileFromMap_Binary(@TempDir Path tmpFolder) throws IOException {
        Map map = generateMapTest();
        FileParserFactory.saveFileFromMap(tmpFolder.resolve("TestBinaryLevel.level").toFile(), map);

        Map testMap = FileParserFactory.loadMapFromFile(tmpFolder.resolve("TestBinaryLevel.level").toFile());
        assertArrayEquals(map.getCleanedMap().getShape(), testMap.getShape());
        for (int i = 0; i < map.getPieces().size(); i++) {
            assertArrayEquals(map.getPieces().get(i).getShape(), testMap.getPieces().get(i).getShape());
        }
    }

    @Test
    void saveLoadFileFromMap_save_Binary(@TempDir Path tmpFolder) throws IOException {
        Map map = generateMapTest();
        FileParserFactory.saveFileFromMap(tmpFolder.resolve("TestBinarySave.slevel").toFile(), map);

        Map testMap = FileParserFactory.loadMapFromFile(tmpFolder.resolve("TestBinarySave.slevel").toFile());
        assertArrayEquals(map.getShape(), testMap.getShape());
        for (int i = 0; i < map.getPieces().size(); i++) {
            assertArrayEquals(map.getPieces().get(i).getShape(), testMap.getPieces().get(i).getShape());
            assertEquals(map.getPieces().get(i).getPosition(), testMap.getPieces().get(i).getPosition());
        }
    }
    @Test
    void saveLoadFileFromMap_Serialized(@TempDir Path tmpFolder) throws IOException {
        Map map = generateMapTest();
        FileParserFactory.saveFileFromMap( tmpFolder.resolve("TestSerializedLevel.serialized").toFile(), map);

        Map testMap = FileParserFactory.loadMapFromFile( tmpFolder.resolve("TestSerializedLevel.serialized").toFile());
        assertArrayEquals(map.getShape(), testMap.getShape());
        for (int i = 0; i < map.getPieces().size(); i++) {
            assertArrayEquals(map.getPieces().get(i).getShape(), testMap.getPieces().get(i).getShape());
        }

    }

    @Test
    void saveLoadFileFromMap_save_Serialized(@TempDir Path tmpFolder) throws IOException{
        Map map = generateMapTest();
        FileParserFactory.saveFileFromMap(tmpFolder.resolve("TestSerializedSave.sserialized").toFile(), map);

        Map testMap = FileParserFactory.loadMapFromFile(tmpFolder.resolve("TestSerializedSave.sserialized").toFile());
        assertArrayEquals(map.getShape(), testMap.getShape());
        for (int i = 0; i < map.getPieces().size(); i++) {
            assertArrayEquals(map.getPieces().get(i).getShape(), testMap.getPieces().get(i).getShape());
            assertEquals(map.getPieces().get(i).getPosition(), testMap.getPieces().get(i).getPosition());
        }
    }
}
