BlindlyTeam/Blindly

View on GitHub
app/src/main/java/ch/epfl/sdp/blindly/main_screen/match/algorithm/UserListFilter.kt

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
package ch.epfl.sdp.blindly.main_screen.match.algorithm

import android.location.Location
import android.os.Build
import androidx.annotation.RequiresApi
import ch.epfl.sdp.blindly.user.User

private const val ONE_KM_IN_METERS = 1000

/**
 * Class used to perform filtering on a list of User. It is used only in the [MatchingAlgorithm],
 * but needed to be tested.
 */
class UserListFilter {

    /**
     * Filters a list of users, so that only the ones that are in the location and age range of
     * the current user remain.
     *
     * @param currentUser the current user
     * @param otherUsers the list of other users
     * @return the filtered list of users
     */
    fun filterLocationAndAgeRange(currentUser: User, otherUsers: List<User>): List<User> {
        val minAge = currentUser.ageRange?.get(0)
        val maxAge = currentUser.ageRange?.get(1)

        return otherUsers.filter { user ->
            User.getUserAge(user) in minAge!!..maxAge!! && isLocatedInUserRadius(currentUser, user)
        }
    }

    /**
     * Does the same checks than [MatchingAlgorithm.getPotentialMatchesFromDatabase], but from the
     * point of view of the other user. The returned list keeps only the users that can be matched
     * with the current user.
     *
     * @param currentUser
     * @param otherUsers
     * @return the filtered list of user
     */
    fun reversePotentialMatch(currentUser: User, otherUsers: List<User>): List<User> {
        val currentUserGender = currentUser.gender
        val currentUserAge = User.getUserAge(currentUser)

        return otherUsers.filter { user ->
            if (user.showMe == EVERYONE) {
                currentUserAge in user.ageRange?.get(0)!!..user.ageRange!![1] &&
                        isLocatedInUserRadius(user, currentUser)
            } else {
                currentUserAge in user.ageRange?.get(0)!!..user.ageRange!![1] &&
                        isLocatedInUserRadius(user, currentUser) &&
                        user.showMe == currentUserGender
            }
        }
    }

    private fun isLocatedInUserRadius(user: User, otherUser: User): Boolean {
        if (user.location == null || otherUser.location == null) {
            throw IllegalArgumentException("Cannot perform distance between null locations")
        }
        val location = createLocation(user.location!!)
        val otherLocation = createLocation(otherUser.location!!)
        val distance = location.distanceTo(otherLocation)
        val radiusInMeters = (user.radius!! * ONE_KM_IN_METERS).toFloat()
        return distance <= radiusInMeters
    }

    private fun createLocation(locationTable: List<Double>): Location {
        val location = Location("")
        location.latitude = locationTable[0]
        location.longitude = locationTable[1]
        return location
    }
}