import clean.architecture.example.data.model.Post


class PostDataRepository private constructor(
        private val localDataSource: PostDataSource,
        private val remoteDataSource: PostDataSource): PostDataSource {

    companion object {
        private var INSTANCE: PostDataRepository? = null

        fun getInstance(localDataSource: PostDataSource, remoteDataSource: PostDataSource): PostDataRepository {
            if (INSTANCE == null) {
                INSTANCE = PostDataRepository(localDataSource, remoteDataSource)
            }
            return INSTANCE!!
        }
    }

    var isCacheDirty = false

    override fun getPosts(userId: Int, callback: PostDataSource.LoadPostsCallback) {

        if (isCacheDirty) {
            getPostsFromServer(userId, callback)
        } else {
            localDataSource.getPosts(userId, object : PostDataSource.LoadPostsCallback {
                override fun onPostsLoaded(posts: List<Post>) {
                    refreshCache()
                    callback.onPostsLoaded(posts)
                }

                override fun onError(t: Throwable) {
                    getPostsFromServer(userId, callback)
                }
            })
        }
    }

    override fun savePost(post: Post) {
        localDataSource.savePost(post)
        remoteDataSource.savePost(post)
    }

    private fun getPostsFromServer(userId: Int, callback: PostDataSource.LoadPostsCallback) {
        remoteDataSource.getPosts(userId, object : PostDataSource.LoadPostsCallback {
            override fun onPostsLoaded(posts: List<Post>) {
                refreshCache()
                refreshLocalDataSource(posts)
                callback.onPostsLoaded(posts)
            }

            override fun onError(t: Throwable) {
                callback.onError(t)
            }
        })
    }

    private fun refreshLocalDataSource(posts: List<Post>) {
        posts.forEach {
            localDataSource.savePost(it)
        }
    }

    private fun refreshCache() {
        isCacheDirty = false
    }
}