package com.bookbase.app.model.repository;

import com.bookbase.app.database.AppDatabase;
import com.bookbase.app.library.addBook.AddBookActivity;
import com.bookbase.app.mainscreen.HomeScreen;
import com.bookbase.app.model.dao.AuthorDao;
import com.bookbase.app.model.dao.BookDao;
import com.bookbase.app.model.dao.GenreDao;
import com.bookbase.app.model.entity.Author;
import com.bookbase.app.model.entity.Book;
import com.bookbase.app.model.entity.Genre;

import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Repository {

    // Thread pool parameters.
    private static int NUM_CORES = Runtime.getRuntime().availableProcessors();
    private static final int KEEP_ALIVE_TIME = 1;
    private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
    private ThreadPoolExecutor pool;

    private static Repository repository;
    private BookDao bookDao;
    private AuthorDao authorDao;
    private GenreDao genreDao;

    private List<Book> books;
    private List<Author> authors;
    private List<Genre> genres;
    private Repository(){
        final BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
        pool = new ThreadPoolExecutor(
                NUM_CORES,
                NUM_CORES,
                KEEP_ALIVE_TIME,
                KEEP_ALIVE_TIME_UNIT,
                workQueue);

        AppDatabase db = AppDatabase.getDatabase(HomeScreen.getContext());
        bookDao = db.bookDao();
        authorDao = db.authorDao();
        genreDao = db.genreDao();

        books = bookDao.getBooks();
        authors = authorDao.getAuthors();
        genres = genreDao.getGenres();
    }

    public static Repository getRepository(){
        if(repository == null){
            repository = new Repository();
        }
        return  repository;
    }

    public List<Book> getBookList() {
        // TODO: Off load to background thread.
        return bookDao.getBooks();
    }

    public void insertBook(final Book book, final AddBookActivity.AddBookCallback callback){
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                long success;
                callback.inProgress();
                success = bookDao.insert(book);
                if(success > 0){
                    callback.onSuccess();
                } else {
                    callback.onFailure();
                }
            }
        };
        pool.execute(runnable);
    }

    public int deleteBook(Book book) {
        // TODO: Off load to background thread.
        return bookDao.deleteBook(book);
    }

    public void insertAuthor(final Author author){
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                authorDao.insert(author);
            }
        };
        pool.execute(runnable);
    }

    public void insertGenre(final Genre genre){
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                genreDao.insert(genre);
            }
        };
        pool.execute(runnable);
    }

    private void refreshBooks(){
        // TODO: Off load to background thread.
        if(books != null){
            bookDao.getBooks();
        }
    }

    private void refreshAuthors(){
        // TODO: Off load to background thread.
        if(authors != null){
            authors = authorDao.getAuthors();
        }
    }

    private void refreshGenres(){
        // TODO: Off load to background thread.
        if(genres != null){
            genres = genreDao.getGenres();
        }
    }

    private void refreshAll(){
        refreshBooks();
        refreshAuthors();
        refreshGenres();
    }


}

@@ -1094,104 +1094,8 @@
 o;%0A%0A
-    private List%3CBook%3E books;%0A    private List%3CAuthor%3E authors;%0A    private List%3CGenre%3E genres;%0A
     
@@ -1568,126 +1568,8 @@
 o();
-%0A%0A        books = bookDao.getBooks();%0A        authors = authorDao.getAuthors();%0A        genres = genreDao.getGenres();
 %0A   
@@ -3045,622 +3045,6 @@
  %7D%0A%0A
-    private void refreshBooks()%7B%0A        // TODO: Off load to background thread.%0A        if(books != null)%7B%0A            bookDao.getBooks();%0A        %7D%0A    %7D%0A%0A    private void refreshAuthors()%7B%0A        // TODO: Off load to background thread.%0A        if(authors != null)%7B%0A            authors = authorDao.getAuthors();%0A        %7D%0A    %7D%0A%0A    private void refreshGenres()%7B%0A        // TODO: Off load to background thread.%0A        if(genres != null)%7B%0A            genres = genreDao.getGenres();%0A        %7D%0A    %7D%0A%0A    private void refreshAll()%7B%0A        refreshBooks();%0A        refreshAuthors();%0A        refreshGenres();%0A    %7D%0A%0A%0A
 %7D%0A

Remove additional redundant code from repository