package ocelot.desktop.util

import java.net.{HttpURLConnection, URL}
import java.time.ZonedDateTime
import scala.util.{Try, Using}

object OcelotOnlineAPI {
  private val UrlInfo: String = "https://ocelot.fomalhaut.me/desktop/info"

  private val RegexDevId = "\"dev\":\\s?\\{.*?\"id\":\\s?\"(.*?)\"".r
  private val RegexDevDate = "\"dev\":\\s?\\{.*?\"date\":\\s?\"(.*?)\"".r
  private val RegexReleaseVersion = "\"release\":\\s?\\{.*?\"version\":\\s?\"(.*?)\"".r
  private val RegexReleaseDate = "\"release\":\\s?\\{.*?\"date\":\\s?\"(.*?)\"".r

  def checkRemoteVersion(callback: Try[Version] => Unit): Unit =
    new Thread(() => callback(getVersion)).start()

  private def getVersion: Try[Version] = Try {
    val source = scala.io.Source.fromURL(UrlInfo)
    val response = source.mkString

    val devId = RegexDevId.findFirstMatchIn(response).map(_.group(1))
    val devDate = RegexDevDate.findFirstMatchIn(response).map(_.group(1))
    val releaseVersion = RegexReleaseVersion.findFirstMatchIn(response).map(_.group(1))
    val releaseDate = RegexReleaseDate.findFirstMatchIn(response).map(_.group(1))
    val version = Version(
      devId,
      devDate.map(it => ZonedDateTime.parse(it)),
      releaseVersion,
      releaseDate.map(it => ZonedDateTime.parse(it)),
    )

    source.close()
    version
  }

  @throws(classOf[java.io.IOException])
  @throws(classOf[java.net.SocketTimeoutException])
  def get(url: String, connectTimeout: Int = 5000, readTimeout: Int = 5000, requestMethod: String = "GET"): String = {
    val connection = new URL(url).openConnection.asInstanceOf[HttpURLConnection]
    connection.setConnectTimeout(connectTimeout)
    connection.setReadTimeout(readTimeout)
    connection.setRequestMethod(requestMethod)
    Using.resource(connection.getInputStream) { inputStream =>
      val content = io.Source.fromInputStream(inputStream).mkString
      content
    }
  }

  case class Version(devId: Option[String], devDate: Option[ZonedDateTime], releaseVersion: Option[String],
                     releaseDate: Option[ZonedDateTime])
}
