/**
 *  Copyright (C) 2021 Anthony Chomienne
 *  This program is free software: you can redistribute it and/or modify it under the terms of the
 *  GNU Affero General Public License as published by the Free Software Foundation, version 3.
 *
 *  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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License along with this program.
 *  If not, see <https://www.gnu.org/licenses/>
 */

package fr.mobdev.peertubelive.manager

import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import fr.mobdev.peertubelive.objects.OAuthData
import fr.mobdev.peertubelive.objects.StreamData
import fr.mobdev.peertubelive.objects.StreamSettings

object DatabaseManager {
    private var databaseHelper: DatabaseHelper? = null


    fun addNewCredentials(context: Context, oAuthData: OAuthData) {
        if (databaseHelper == null)
            databaseHelper = DatabaseHelper(context)

        val values = ContentValues()
        values.put(DatabaseHelper.CREDS_BASE_URL,oAuthData.baseUrl)
        values.put(DatabaseHelper.CREDS_USERNAME,oAuthData.username)
        values.put(DatabaseHelper.CREDS_CLIENT_ID,oAuthData.clientId)
        values.put(DatabaseHelper.CREDS_CLIENT_SECRET,oAuthData.clientSecret)
        values.put(DatabaseHelper.CREDS_ACCESS_TOKEN,oAuthData.accessToken)
        values.put(DatabaseHelper.CREDS_TOKEN_TYPE,oAuthData.tokenType)
        values.put(DatabaseHelper.CREDS_EXPIRES,oAuthData.expires)
        values.put(DatabaseHelper.CREDS_REFRESH_TOKEN,oAuthData.refreshToken)
        values.put(DatabaseHelper.CREDS_REFRESH_EXPIRES,oAuthData.refreshTokenExpires)
        databaseHelper?.insert(DatabaseHelper.TABLE_CREDS,values)

    }

    fun updateCredentials(context: Context, oAuthData: OAuthData) {
        if (databaseHelper == null)
            databaseHelper = DatabaseHelper(context)

        val values = ContentValues()
        val whereClause = "${DatabaseHelper.CREDS_USERNAME} = ? AND ${DatabaseHelper.CREDS_BASE_URL} = ? AND ${DatabaseHelper.CREDS_CLIENT_SECRET} = ?"
        val whereArgs = arrayOf(oAuthData.username , oAuthData.baseUrl , oAuthData.clientSecret)
        values.put(DatabaseHelper.CREDS_ACCESS_TOKEN,oAuthData.accessToken)
        values.put(DatabaseHelper.CREDS_TOKEN_TYPE,oAuthData.tokenType)
        values.put(DatabaseHelper.CREDS_EXPIRES,oAuthData.expires)
        values.put(DatabaseHelper.CREDS_REFRESH_TOKEN,oAuthData.refreshToken)
        values.put(DatabaseHelper.CREDS_REFRESH_EXPIRES,oAuthData.refreshTokenExpires)
        databaseHelper?.update(DatabaseHelper.TABLE_CREDS,values,whereClause,whereArgs)
    }

    fun getCredentials(context: Context): List<OAuthData>  {
        if (databaseHelper == null)
            databaseHelper = DatabaseHelper(context)
        val oAuthDatas: ArrayList<OAuthData> = ArrayList()
        val cursor: Cursor? = databaseHelper?.query(DatabaseHelper.TABLE_CREDS,null,null,null)
        while (cursor?.moveToNext() == true) {
            var col = 1
            val username: String = cursor.getString(col++)
            val baseUrl: String = cursor.getString(col++)
            val clientId: String = cursor.getString(col++)
            val clientSecret: String = cursor.getString(col++)
            val accessToken: String = cursor.getString(col++)
            val tokenType: String = cursor.getString(col++)
            val expires: Long = cursor.getLong(col++)
            val refreshToken: String = cursor.getString(col++)
            val refreshTokenExpires: Long = cursor.getLong(col)
            var oAuthData = OAuthData(baseUrl,username,clientId,clientSecret,accessToken,tokenType,expires,refreshToken,refreshTokenExpires)
            oAuthDatas.add(oAuthData)

        }
        cursor?.close()
        return oAuthDatas
    }

    fun existsCredential(context: Context, url: String, username: String): Boolean {
        if (databaseHelper == null)
            databaseHelper = DatabaseHelper(context)
        val columns = arrayOf(DatabaseHelper.CREDS_BASE_URL, DatabaseHelper.CREDS_USERNAME)
        val whereClause = "${DatabaseHelper.CREDS_USERNAME} = ? AND ${DatabaseHelper.CREDS_BASE_URL} = ?"
        val whereArgs = arrayOf(username, url)
        val cursor: Cursor? = databaseHelper?.query(DatabaseHelper.TABLE_CREDS,columns,whereClause,whereArgs)
        val exist = cursor?.count != 0
        cursor?.close()
        return exist
    }

    fun deleteAccount(context: Context, oAuthData: OAuthData) {
        if (databaseHelper == null)
            databaseHelper = DatabaseHelper(context)
        val whereClause = "${DatabaseHelper.CREDS_USERNAME} = ? AND ${DatabaseHelper.CREDS_BASE_URL} = ? AND ${DatabaseHelper.CREDS_CLIENT_ID} = ?"
        val whereArgs = arrayOf(oAuthData.username, oAuthData.baseUrl, oAuthData.clientId)
        databaseHelper?.delete(DatabaseHelper.TABLE_CREDS,whereClause,whereArgs)
    }

    fun getStreamSettings(context: Context): StreamSettings?  {
        if (databaseHelper == null)
            databaseHelper = DatabaseHelper(context)

        val cursor: Cursor? = databaseHelper?.query(DatabaseHelper.TABLE_STREAM_SETTINGS,null,null,null)
        var streamSettings: StreamSettings? = null
        if(cursor?.moveToNext() == true) {
            var col = 1
            val title: String = cursor.getString(col++)
            val category: Int = cursor.getInt(col++)
            val privacy: Int = cursor.getInt(col++)
            val language: String? = cursor.getString(col++)
            val licence: Int = cursor.getInt(col++)
            val comments: Boolean = cursor.getInt(col++) == 1
            val download: Boolean = cursor.getInt(col++) == 1
            val saveReplay: Boolean = cursor.getInt(col++) == 1
            val nsfw: Boolean = cursor.getInt(col++) == 1
            val resolution: StreamData.STREAM_RESOLUTION = StreamData.STREAM_RESOLUTION.values()[cursor.getInt(col)]
            streamSettings = StreamSettings(title,0,privacy,category,language,licence,null,comments,download,nsfw,saveReplay,resolution)
        }
        cursor?.close()
        return streamSettings
    }

    fun updateStreamSettings(context: Context, streamSettings: StreamSettings) {
        if (databaseHelper == null)
            databaseHelper = DatabaseHelper(context)
        val values = ContentValues()
        values.put(DatabaseHelper.SETS_TITLE,streamSettings.title)
        values.put(DatabaseHelper.SETS_PRIVACY,streamSettings.privacy)
        values.put(DatabaseHelper.SETS_CATEGORY,streamSettings.category)
        values.put(DatabaseHelper.SETS_COMMENTS,streamSettings.comments)
        values.put(DatabaseHelper.SETS_DOWNLOAD,streamSettings.download)
        values.put(DatabaseHelper.SETS_NSFW,streamSettings.nsfw)
        values.put(DatabaseHelper.SETS_REPLAY,streamSettings.saveReplay)
        values.put(DatabaseHelper.SETS_LANGUAGE,streamSettings.language)
        values.put(DatabaseHelper.SETS_LICENCE,streamSettings.licence)
        values.put(DatabaseHelper.SETS_RESOLUTION,streamSettings.resolution.ordinal)


        val whereClause = "id = ?"
        val whereArgs: Array<String?> = arrayOf("1")
        databaseHelper?.update(DatabaseHelper.TABLE_STREAM_SETTINGS,values,whereClause,whereArgs)
    }
}