package com.rightfromleftsw.weather.ui.injection.module

import android.app.Application
import android.content.Context
import com.rightfromleftsw.weather.data.WeatherDataRepository
import com.rightfromleftsw.weather.data.executor.JobExecutor
import com.rightfromleftsw.weather.data.mapper.WeatherMapper
import com.rightfromleftsw.weather.data.repository.IWeatherLocal
import com.rightfromleftsw.weather.data.repository.IWeatherRemote
import com.rightfromleftsw.weather.domain.executor.PostExecutionThread
import com.rightfromleftsw.weather.domain.executor.ThreadExecutor
import com.rightfromleftsw.weather.domain.repository.IWeatherRepository
import com.rightfromleftsw.weather.localdata.WeatherLocalDataImpl
import com.rightfromleftsw.weather.localdata.WeatherSharedPrefs
import com.rightfromleftsw.weather.remote.WeatherRemoteImpl
import com.rightfromleftsw.weather.remote.WeatherService
import com.rightfromleftsw.weather.remote.WeatherServiceFactory
import com.rightfromleftsw.weather.remote.mapper.WeatherRemoteEntityMapper
import com.rightfromleftsw.weather.ui.BuildConfig
import com.rightfromleftsw.weather.ui.UiThread
import com.rightfromleftsw.weather.ui.injection.scopes.PerApplication
import dagger.Module
import dagger.Provides

/**
 * Module used to provide dependencies at an application-level.
 */
@Module
open class ApplicationModule {

    @Provides
    @PerApplication
    fun provideContext(application: Application): Context {
        return application
    }

    @Provides
    @PerApplication
    internal fun providePreferencesHelper(context: Context): WeatherSharedPrefs {
        return WeatherSharedPrefs(context)
    }


    @Provides
    @PerApplication
    internal fun provideRepository(localDataStore: IWeatherLocal,
                                   remoteDataStore: IWeatherRemote,
                                   mapper: WeatherMapper): IWeatherRepository {
        return WeatherDataRepository(localDataStore, remoteDataStore, mapper)
    }



    @Provides
    @PerApplication
    internal fun provideIWeatherLocal(  //db: WeatherDatabase,
                                      //dbMapper: WeatherDbMapper,
                                      sharedPrefs: WeatherSharedPrefs): IWeatherLocal {
        return WeatherLocalDataImpl(sharedPrefs)
    }

    @Provides
    @PerApplication
    internal fun provideIWeatherRemote(service: WeatherService,
                                       remoteEntityMapper: WeatherRemoteEntityMapper): IWeatherRemote {
        return WeatherRemoteImpl(service, remoteEntityMapper)
    }

    @Provides
    @PerApplication
    internal fun provideThreadExecutor(jobExecutor: JobExecutor): ThreadExecutor {
        return jobExecutor
    }

    @Provides
    @PerApplication
    internal fun providePostExecutionThread(uiThread: UiThread): PostExecutionThread {
        return uiThread
    }

    @Provides
    @PerApplication
    internal fun provideWeatherService(): WeatherService {
        return WeatherServiceFactory.makeWeatherService(BuildConfig.DEBUG)
    }
}
