package com.suno.android.common_data.use_case import android.content.ContentResolver import android.net.Uri import android.provider.OpenableColumns import arrow.core.Either import arrow.core.left import arrow.core.right import com.suno.android.common_data.entities.ImageUploadConfig import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import javax.inject.Inject sealed class ImageValidationError { object FileTooLarge : ImageValidationError() object UnsupportedFormat : ImageValidationError() object FileNotFound : ImageValidationError() data class UnknownError( val throwable: Throwable, ) : ImageValidationError() } class ValidateImageUploadUseCase @Inject constructor( private val contentResolver: ContentResolver, ) { suspend operator fun invoke( uri: Uri, config: ImageUploadConfig, ): Either = withContext(Dispatchers.IO) { try { // Check if file exists and get size val cursor = contentResolver.query(uri, null, null, null, null) ?: return@withContext ImageValidationError.FileNotFound.left() cursor.use { if (!it.moveToFirst()) { return@withContext ImageValidationError.FileNotFound.left() } val sizeIndex = it.getColumnIndex(OpenableColumns.SIZE) if (sizeIndex != -1) { val fileSize = it.getLong(sizeIndex) if (fileSize > config.maxFileSizeBytes) { return@withContext ImageValidationError.FileTooLarge.left() } } // Check file type from MIME type val mimeType = contentResolver.getType(uri) if (!isValidImageMimeType(mimeType)) { return@withContext ImageValidationError.UnsupportedFormat.left() } } Unit.right() } catch (e: SecurityException) { // Log the original exception to preserve debugging information ImageValidationError.UnknownError(e).left() } catch (e: IllegalArgumentException) { ImageValidationError.UnknownError(e).left() } catch (e: IllegalStateException) { ImageValidationError.UnknownError(e).left() } } private fun isValidImageMimeType( mimeType: String?, ): Boolean = when (mimeType) { "image/jpeg", "image/jpg", "image/png", "image/webp", "image/bmp", -> true else -> false } }