/**
 * ProjectLaogai
 *
 * Copyright 2019-2020  <seil0@mosad.xyz>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 *
 */

package org.mosad.seil0.projectlaogai.controller

import com.google.gson.Gson
import com.google.gson.JsonParser
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.*
import org.mosad.seil0.projectlaogai.util.*
import java.net.URL

/**
 * This Controller calls the tcor api,
 * all functions return tcor api objects
 */
class TCoRAPIController {

    companion object {
        private const val tcorBaseURL = "https://tcor.mosad.xyz"

        /**
         * Get a array of all currently available courses at the tcor API.
         * Read the json object from tcor api
         */

        fun getCourseListNEW(): CoursesList {
            val url = URL("$tcorBaseURL/courseList")

            return Gson().fromJson(url.readText(), CoursesList().javaClass)
        }

        /**
         * Get current and next weeks mensa menus from the tcor API.
         * Read the json object from tcor api
         */
        fun getMensaMenu(): MensaMenu {
            val url = URL("$tcorBaseURL/mensamenu")

            return Gson().fromJson(url.readText(), MensaMenu().javaClass)
        }

        /**
         * Get the timetable for "courseName" at week "week"
         * Read the json object from tcor api
         * @param courseName the course name (e.g AI1)
         * @param week the week to update (0 for the current and so on)
         */
        fun getTimetable(courseName: String, week: Int): TimetableWeek {
            val url = URL("$tcorBaseURL/timetable?course=$courseName&week=$week")
            val timetableCW = Gson().fromJson(url.readText(), TimetableCourseWeek().javaClass)

            return TimetableWeek(
                timetableCW.meta.weekIndex,
                timetableCW.meta.weekNumberYear,
                timetableCW.timetable.days
            )
        }

        /**
         * Get all lessons for a course at one week (async)
         * @param courseName the course name
         * @param week the week to look up
         */
        fun getSubjectListAsync(courseName: String, week: Int): Deferred<ArrayList<String>> {
            val url = URL("$tcorBaseURL/subjectList?course=$courseName&week=$week")

            return GlobalScope.async {
                Gson().fromJson(url.readText(), ArrayList<String>()::class.java)
            }
        }

        /**
         * Get all occurrences of a lesson for a course at one week
         * @param courseName the course name
         * @param subject the subject to search for
         * @param week the week to look up
         */
        fun getLessons(courseName: String, subject: String, week: Int): ArrayList<Lesson> {
            val url = URL("$tcorBaseURL/lessons?course=$courseName&subject=$subject&week=$week")
            var array: ArrayList<Lesson>

            runBlocking {
                withContext(Dispatchers.Default) {
                    array = Gson().fromJson(
                        JsonParser.parseString(url.readText()).asJsonArray,
                        object : TypeToken<ArrayList<Lesson>>() {}.type
                    )
                }
            }

            return array
        }

    }

}