package com.bellini.recipecatalog.service.v1.book;

import java.time.Instant;
import java.util.Collection;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;

import com.bellini.recipecatalog.dao.v1.book.BookRepository;
import com.bellini.recipecatalog.exception.book.DuplicateBookException;
import com.bellini.recipecatalog.exception.book.NotExistingBookException;
import com.bellini.recipecatalog.model.v1.Book;

@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookRepository repo;

    @Override
    public Page<Book> getAll(Pageable pageable) {
        return repo.findAll(createSortedPageRequest(pageable));
    }

    private PageRequest createSortedPageRequest(Pageable pageable) {
        Sort.Order order = new Sort.Order(Direction.ASC, "Title").ignoreCase();
        Sort sort = Sort.by(order);
        PageRequest pgReq = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), sort);
        return pgReq;
    }

    @Override
    public Book create(Book b) {
        if (!repo.findByTitleIgnoreCase(b.getTitle()).isEmpty()) {
            throw new DuplicateBookException(b);
        }
        // setting creation/modification timestamps
        b.setCreationTime(Instant.now());
        b.setLastModificationTime(Instant.now());
        return repo.save(b);
    }

    @Override
    public Page<Book> get(String title, Pageable pageable) {
        return repo.findByTitleIgnoreCaseContaining(title, createSortedPageRequest(pageable));
    }

    @Override
    public Book get(Long id) {
        Optional<Book> optBk = repo.findById(id);
        if (!optBk.isPresent()) {
            throw new NotExistingBookException(id);
        }
        return optBk.get();
    }

    @Override
    public Book update(Long id, Book b) {
        if (id == null) {
            throw new IllegalArgumentException("Invalid id");
        }
        if (b == null || StringUtils.isEmpty(b.getTitle())) {
            throw new IllegalArgumentException("Invalid book");
        }
        // FIXME refactor
        // search for name conflict
        Collection<Book> soughtList = repo.findByTitleIgnoreCase(b.getTitle());
        if (soughtList.isEmpty() || soughtList.iterator().next().getId().equals(id)) {
            Optional<Book> toUpdateOpt = repo.findById(id);
            if (!toUpdateOpt.isPresent()) {
                throw new NotExistingBookException(id);
            }
            // update only the title
            Book toUpdate = toUpdateOpt.get();
            toUpdate.setTitle(b.getTitle());
            return repo.save(id, toUpdate);
        }
        throw new DuplicateBookException(b);
    }

    @Override
    public void delete(Long id) {
        repo.deleteById(id);
    }

}

@@ -49,34 +49,8 @@
 k;%0A%0A
-import java.time.Instant;%0A
 impo
@@ -302,164 +302,12 @@
 Page
-Request;%0Aimport org.springframework.data.domain.Pageable;%0Aimport org.springframework.data.domain.Sort;%0Aimport org.springframework.data.domain.Sort.Direction
+able
 ;%0Aim
@@ -817,356 +817,17 @@
 All(
-createSortedPageRequest(pageable));%0A    %7D%0A%0A    private PageRequest createSortedPageRequest(Pageable pageable) %7B%0A        Sort.Order order = new Sort.Order(Direction.ASC, %22Title%22).ignoreCase();%0A        Sort sort = Sort.by(order);%0A        PageRequest pgReq = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), sort);%0A        return pgReq
+pageable)
 ;%0A  
@@ -1008,152 +1008,8 @@
   %7D%0A
-        // setting creation/modification timestamps%0A        b.setCreationTime(Instant.now());%0A        b.setLastModificationTime(Instant.now());%0A
     
@@ -1178,32 +1178,8 @@
 le, 
-createSortedPageRequest(
 page
@@ -1183,17 +1183,16 @@
 ageable)
-)
 ;%0A    %7D%0A

Remove old method and service implementation