package ch.zhaw.gartenverwaltung.io;

import ch.zhaw.gartenverwaltung.types.Task;
import org.junit.jupiter.api.*;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

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

public class JsonTaskListTest {

    TaskList testDatabase;
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    private final URL dbDataSource = this.getClass().getResource("test-taskdb.json");
    private final URL testFile = this.getClass().getResource("template-taskdb.json");

    @BeforeEach
    void connectToDb() throws URISyntaxException, IOException {
        assertNotNull(testFile);
        assertNotNull(dbDataSource);
        Files.copy(Path.of(testFile.toURI()), Path.of(dbDataSource.toURI()), StandardCopyOption.REPLACE_EXISTING);
        testDatabase = new JsonTaskList(dbDataSource);
    }

    @Test
    @DisplayName("Check if results are retrieved completely")
    void getTasks() {

        List<Task> taskList;
        try {
            taskList = testDatabase.getTaskList(LocalDate.parse("2022-04-30", formatter),
                    LocalDate.parse("2022-05-31", formatter));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        Assertions.assertEquals(3, taskList.size());

    }

    @Disabled("disabled until adding works.")
    @Test
    @DisplayName("Add task.")
    void addTask() {
        Task task = new Task("Testtask", "This is a test Task.", LocalDate.parse("01.05.2022", formatter), 1);
        try {
            testDatabase.saveTask(task);
            List<Task> taskList;
            try {
                taskList = testDatabase.getTaskList(LocalDate.parse("30.04.2022", formatter),
                        LocalDate.parse("31.05.2022", formatter));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            Assertions.assertEquals(4, taskList.size());

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Test
    @DisplayName("Remove task.")
    void removeTask() {
        Task task = new Task("Dummy", "Dummy", LocalDate.parse("2022-05-31", formatter), 1)
                .withId(2);
        try {
            testDatabase.removeTask(task);
            List<Task> taskList;

            taskList = testDatabase.getTaskList(LocalDate.parse("2022-04-30", formatter),
                    LocalDate.parse("2022-05-31", formatter));

            Assertions.assertEquals(2, taskList.size());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }


    @Test
    void getTaskForCrop() {
        List<Task> taskList;
        try {
            taskList = testDatabase.getTaskForCrop(0);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        Assertions.assertEquals(6, taskList.size());

    }

    @Disabled("Disabled until removing works")
    @Test
    void removeTasksForCrop() {
        List<Task> taskList;
        try {
            testDatabase.removeTasksForCrop(0);
            taskList = testDatabase.getTaskForCrop(0);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        Assertions.assertEquals(0, taskList.size());
    }
}