package org.bookdash.android.data.book;
import android.support.annotation.NonNull;
import org.bookdash.android.data.database.firebase.BookDatabase;
import org.bookdash.android.domain.model.firebase.FireBookDetails;
import org.bookdash.android.domain.model.firebase.FireContributor;
import org.bookdash.android.domain.model.firebase.FireLanguage;
import org.bookdash.android.domain.model.firebase.FireRole;
import java.util.List;
import rx.Observable;
import rx.functions.Func1;
import rx.functions.Func2;
public class BookServiceImpl implements BookService {
private final BookDatabase bookDatabase;
public BookServiceImpl(BookDatabase bookDatabase) {
this.bookDatabase = bookDatabase;
}
@Override
public Observable<List<FireLanguage>> getLanguages() {
return bookDatabase.getLanguages().flatMap(filterEnabledLanguages());
}
@Override
public Observable<List<FireBookDetails>> getBooksForLanguage(final FireLanguage language) {
return bookDatabase.getBooks().flatMap(filterEnabledBooks()).flatMap(filterLanguage(language));
}
private Func1<List<FireBookDetails>, Observable<List<FireBookDetails>>> filterEnabledBooks() {
return new Func1<List<FireBookDetails>, Observable<List<FireBookDetails>>>() {
@Override
public Observable<List<FireBookDetails>> call(final List<FireBookDetails> fireBookDetailses) {
return Observable.from(fireBookDetailses).filter(new Func1<FireBookDetails, Boolean>() {
@Override
public Boolean call(FireBookDetails bookDetails) {
return bookDetails.isBookEnabled();
}
}).toList();
}
};
}
@Override
public Observable<List<FireContributor>> getContributorsForBook(final FireBookDetails book) {
return Observable.just(book.getContributorsIndexList()).flatMap(getContributorsFromIds());
}
@NonNull
private Func1<List<FireBookDetails>, Observable<List<FireBookDetails>>> filterLanguage(
final FireLanguage fireLanguage) {
return new Func1<List<FireBookDetails>, Observable<List<FireBookDetails>>>() {
@Override
public Observable<List<FireBookDetails>> call(final List<FireBookDetails> fireBookList) {
return Observable.from(fireBookList).filter(new Func1<FireBookDetails, Boolean>() {
@Override
public Boolean call(final FireBookDetails fireBookDetails) {
return fireBookDetails.getBookLanguage().equalsIgnoreCase(fireLanguage.getId());
}
}).toList();
}
};
}
@Override
public Observable<List<FireBookDetails>> getDownloadedBooks() {
return bookDatabase.getBooks().flatMap(filterDownloadedBooks());
}
@Override
public Observable<List<FireBookDetails>> searchBooks(final String searchTerm) {
return bookDatabase.getBooks().flatMap(new Func1<List<FireBookDetails>, Observable<List<FireBookDetails>>>() {
@Override
public Observable<List<FireBookDetails>> call(final List<FireBookDetails> fireBookDetailses) {
return Observable.from(fireBookDetailses).filter(new Func1<FireBookDetails, Boolean>() {
@Override
public Boolean call(final FireBookDetails fireBookDetails) {
return fireBookDetails.getBookTitle().toLowerCase().contains(searchTerm.toLowerCase());
}
}).toList();
}
});
}
@NonNull
private Func1<List<FireBookDetails>, Observable<List<FireBookDetails>>> filterDownloadedBooks() {
return new Func1<List<FireBookDetails>, Observable<List<FireBookDetails>>>() {
@Override
public Observable<List<FireBookDetails>> call(List<FireBookDetails> fireBookDetailses) {
return Observable.from(fireBookDetailses).filter(new Func1<FireBookDetails, Boolean>() {
@Override
public Boolean call(FireBookDetails bookDetails) {
return bookDetails.isDownloadedAlready();
}
}).toList();
}
};
}
private Func1<List<String>, Observable<List<FireContributor>>> getContributorsFromIds() {
return new Func1<List<String>, Observable<List<FireContributor>>>() {
@Override
public Observable<List<FireContributor>> call(List<String> userIds) {
return Observable.from(userIds).flatMap(new Func1<String, Observable<FireContributor>>() {
@Override
public Observable<FireContributor> call(final String s) {
return bookDatabase.getContributorById(s).flatMap(getRolesForContributor());
}
}).toList();
}
};
}
private Func1<FireContributor, Observable<FireContributor>> getRolesForContributor() {
return new Func1<FireContributor, Observable<FireContributor>>() {
@Override
public Observable<FireContributor> call(final FireContributor fireContributor) {
return Observable.zip(Observable.just(fireContributor),
Observable.from(fireContributor.getRoleIds()).flatMap(getRole()).toList(),
new Func2<FireContributor, List<FireRole>, FireContributor>() {
@Override
public FireContributor call(final FireContributor fireContributor,
final List<FireRole> fireRoles) {
fireContributor.setActualRoles(fireRoles);
return fireContributor;
}
});
}
};
}
private Func1<String, Observable<FireRole>> getRole() {
return new Func1<String, Observable<FireRole>>() {
@Override
public Observable<FireRole> call(final String s) {
return bookDatabase.getRoleById(s);
}
};
}
private Func1<List<FireLanguage>, Observable<List<FireLanguage>>> filterEnabledLanguages() {
return new Func1<List<FireLanguage>, Observable<List<FireLanguage>>>() {
@Override
public Observable<List<FireLanguage>> call(final List<FireLanguage> fireLanguages) {
return Observable.from(fireLanguages).filter(new Func1<FireLanguage, Boolean>() {
@Override
public Boolean call(final FireLanguage fireLanguage) {
return fireLanguage.isEnabled();
}
}).toList();
}
};
}
}