package ulcrs.data;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import ulcrs.models.course.Course;
import ulcrs.models.shift.Shift;
import ulcrs.models.tutor.Tutor;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.util.List;

public class DataStore {

    private List<Tutor> tutors;
    private List<Course> courses;
    private List<Shift> shifts;
    private LocalDateTime timeFetched = LocalDateTime.MIN;

    private static DataStore dataStore;

    public static DataStore getInstance() {
        if (dataStore == null) {
            dataStore = new DataStore();
        }
        return dataStore;
    }


    public static Tutor getTutor(int id) {
        // TODO have this reference DataStore.tutors
        InputStream is = DataStore.class.getClassLoader().getResourceAsStream("mockTutorsFull.json");
        JsonReader reader = new JsonReader(new InputStreamReader(is));

        List<Tutor> tutors = new Gson().fromJson(reader, new TypeToken<List<Tutor>>() {}.getType());

        return tutors.stream()
                .filter(tutor -> tutor.getId() == id)
                .findFirst()
                .orElse(null);
    }

    public static Course getCourse(int id) {
        // TODO have this reference DataStore.courses
        InputStream is = DataStore.class.getClassLoader().getResourceAsStream("mockCoursesFull.json");
        JsonReader reader = new JsonReader(new InputStreamReader(is));

        List<Course> courses = new Gson().fromJson(reader, new TypeToken<List<Course>>() {}.getType());

        return getInstance().courses.stream()
                .filter(course -> course.getId() == id)
                .findFirst()
                .orElse(null);
    }

    public static Shift getShift(int id) {
        return getInstance().shifts.stream()
                .filter(s -> s.getId() == id)
                .findFirst()
                .orElse(null);
    }

    public static List<Tutor> getTutors() {
        if (requiresFetch(getInstance().tutors)) {
            // Fetch from ULC - TODO

            // (For now, just set tutors to be this mock data)
            InputStream is = DataStore.class.getClassLoader().getResourceAsStream("mockTutors.json");
            JsonReader reader = new JsonReader(new InputStreamReader(is));

            getInstance().tutors = new Gson().fromJson(reader, new TypeToken<List<Tutor>>() {}.getType());
        }

        return getInstance().tutors;
    }

    public static List<Course> getCourses() {
        if (requiresFetch(getInstance().courses)) {
            // Fetch from ULC - TODO

            // (For now, just set courses to be this mock data)
            InputStream is = DataStore.class.getClassLoader().getResourceAsStream("mockCoursesFull.json"); //mockCoursesNoTime.json");
            JsonReader reader = new JsonReader(new InputStreamReader(is));
            List<Course> courses = new Gson().fromJson(reader, new TypeToken<List<Course>>() {}.getType());
            getInstance().courses = courses;
        }

        return getInstance().courses;
    }

    private static <T> boolean requiresFetch(T reference) {
        return reference == null;
    }
}

@@ -1360,338 +1360,91 @@
     
-// TODO have this reference DataStore.courses%0D%0A        InputStream is = DataStore.class.getClassLoader().getResourceAsStream(%22mockCoursesFull.json%22);%0D%0A        JsonReader reader = new JsonReader(new InputStreamReader(is));%0D%0A%0D%0A        List%3CCourse%3E courses = new Gson().fromJson(reader, new TypeToken%3CList%3CCourse%3E%3E() %7B%7D.getType());%0D%0A
+if (requiresFetch(getInstance().courses)) %7B%0D%0A        %09fetch();%0D%0A        %7D%0D%0A        
 %0D%0A  
@@ -2516,79 +2516,338 @@
 DO%0D%0A
-%0D%0A            // (For now, just set courses to be this mock data)%0D%0A    
+        %09fetch();%0D%0A        %7D%0D%0A%0D%0A        return getInstance().courses;%0D%0A    %7D%0D%0A%0D%0A    private static %3CT%3E boolean requiresFetch(T reference) %7B%0D%0A        return reference == null;%0D%0A    %7D%0D%0A    %0D%0A    private static void fetch() %7B%0D%0A    %09// Fetch from ULC - TODO%0D%0A    %09// For now, just get data from mock data    %09%0D%0A    %09%0D%0A    %09// Course%0D%0A
     
@@ -2948,42 +2948,10 @@
 n%22);
- //mockCoursesNoTime.json%22);%0D%0A    
+%0D%0A
     
@@ -3014,28 +3014,24 @@
 ader(is));%0D%0A
-    
         List
@@ -3123,36 +3123,32 @@
 pe());%0D%0A        
-  
-  
 getInstance().co
@@ -3173,166 +3173,21 @@
     
-    %7D%0D%0A%0D%0A        return getInstance().courses;%0D%0A    %7D%0D%0A%0D%0A    private static %3CT%3E boolean requiresFetch(T reference) %7B%0D%0A        return reference == null;%0D%0A    %7D
+%7D%0D%0A    %0D%0A    
 %0D%0A%7D%0D

create fetch() function in DataStore