package net.pokeranalytics.android.model.filter

import io.realm.RealmModel
import net.pokeranalytics.android.model.realm.ComputableResult
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.SessionSet

/**
 * We want to be able to store filters in the database:
 * - filters can be a combination of sub filters
 * - filters can be applied to different type of objects: Sessions, Hands, Transactions...
 * - filters can be applied to a list of different type of objects (feed)
 *
 * A filter is described by the following:
 * - a data type: Session, Hands...
 * - a field: table size of a Session
 * - an operator: equal, >=, <...
 * - a value: an id, a number, a date...
 *
 * We can decide to have a collection of [operator, value] for a field
 *
 * Combination:
 * - multiple datatype filters should be handled as 'OR'
 * - multiple field filters should be handled as 'AND'
 * - multiple '=' filters as 'OR'
 * - multiple 'Greater than', 'less than' as 'AND'
 * - multiple numericValues as 'OR'
 *
 * Also:
 * A filter should be able to be converted into a Realm query
 *
 */

class UnmanagedFilterField(message: String) : Exception(message) {

}

/**
 * Companion-level Interface to indicate an RealmObject class can be filtered and to provide all the fieldNames (eg: parameter's path) needed to be query on.
 */
interface Filterable : RealmModel {

	/**
	 * return the path of the parameter used in the [QueryCondition] related to this entity
	 */
//    fun fieldNameForQueryType(queryCondition: QueryCondition) : String?

}

class FilterHelper {

	companion object {

		inline fun <reified T : Filterable> fieldNameForQueryType(queryCondition: QueryCondition): String? {

			return when (T::class.java) {
				Session::class.java -> Session.fieldNameForQueryType(queryCondition)
				ComputableResult::class.java -> ComputableResult.fieldNameForQueryType(queryCondition)
				SessionSet::class.java -> SessionSet.fieldNameForQueryType(queryCondition)
				else -> {
					throw UnmanagedFilterField("Filterable type fields are not defined for class ${T::class}")
				}
			}

		}

	}

}

//
//fun MutableList<Filterable>.filter(filter: FilterCondition) : List<Filterable> {
//
//    return this.filter { f ->
//        return@filter true
//    }
//}


// doesnt compile: Class "FilterableRealmObject" must contain at least 1 persistable field.

//class FilterableRealmObject : RealmObject(), Filterable {
//
//}