package org.aming.web.qq.service.impl;

import org.aming.web.qq.domain.Message;
import org.aming.web.qq.domain.Page;
import org.aming.web.qq.domain.TimeInterval;
import org.aming.web.qq.domain.User;
import org.aming.web.qq.exceptions.WebQQDaoException;
import org.aming.web.qq.exceptions.WebQQServiceException;
import org.aming.web.qq.repository.jdbc.MessageDao;
import org.aming.web.qq.repository.jdbc.UserDao;
import org.aming.web.qq.service.MessageService;
import org.aming.web.qq.utils.NumberUtils;
import org.aming.web.qq.utils.SecurityContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * @author daming
 * @version 2017/10/5.
 */
@Service
@Transactional
public class MessageServiceImpl implements MessageService{

    private MessageDao messageDao;
    private UserDao userDao;


    @Override
    public boolean saveMessage(Message message) throws WebQQServiceException {
        if(Objects.isNull(message.getSendUser())){
           message.setSendUser(new User(SecurityContextUtils.getCurrentUser()));
        }
        return doSaveMessage(message);
    }

    private boolean doSaveMessage(Message message) {
        return NumberUtils.isGreaterThanZero(messageDao.saveMessage(message));
    }

    @Override
    public List<Message> getMessage(@Nullable UserDetails sendUser, @Nonnull UserDetails receiveUser, Page page) throws WebQQServiceException {
        try{
            if(Objects.isNull(sendUser)){
                sendUser = SecurityContextUtils.getCurrentUser();
            }
            List<Message> result = doGetMessage(
                    userDao.loadUserByUsername(sendUser.getUsername()), //param: sendUser
                    userDao.loadUserByUsername(receiveUser.getUsername()), //param: receiveUser
                    page //param: page
            );
            return result
                    .stream()
                    .sorted(
                            Comparator
                                    .comparing(
                                            Message ::getSendDate
                                    ))
                    .collect(
                            Collectors
                                    .toList()
                    );
        } catch (WebQQDaoException ex) {
            throw new WebQQServiceException("获取聊天记录失败", ex);
        } catch (Exception ex) {
            throw new WebQQServiceException("获取聊天记录失败");
        }

    }

    @Override
    public List<Message> getMessage(@Nullable UserDetails sendUser,@Nonnull UserDetails receiveUser, TimeInterval timeInterval) throws WebQQServiceException {
        try{
            if(Objects.isNull(sendUser)){
                sendUser = SecurityContextUtils.getCurrentUser();
            }
            List<Message> result = doGetMessage(
                    userDao.loadUserByUsername(sendUser.getUsername()), //param: sendUser
                    userDao.loadUserByUsername(receiveUser.getUsername()), //param: receiveUser
                    timeInterval //param: timeInterval
            );
            return result
                    .stream()
                    .sorted(
                            Comparator
                                    .comparing(
                                            Message ::getSendDate
                                    ))
                    .collect(
                            Collectors
                                    .toList()
                    );
        } catch (WebQQDaoException ex) {
            throw new WebQQServiceException("获取聊天记录失败", ex);
        } catch (Exception ex) {
            throw new WebQQServiceException("获取聊天记录失败");
        }

    }

    private List<Message> doGetMessage(User sendUser,User receiveUser,Page page) throws WebQQDaoException {
        return messageDao.getMessage(sendUser,receiveUser,page);
    }

    private List<Message> doGetMessage(User sendUser,User receiveUser,TimeInterval TimeInterval) throws WebQQDaoException {
        return messageDao.getMessage(sendUser,receiveUser,TimeInterval);
    }

    @Autowired
    public void setMessageDao(MessageDao messageDao){
        this.messageDao = messageDao;
    }
    @Autowired
    public void setUserDao(UserDao userDao){
        this.userDao = userDao;
    }

}

@@ -611,16 +611,71 @@
 owired;%0A
+import org.springframework.cache.annotation.Cacheable;%0A
 import o
@@ -728,24 +728,24 @@
 serDetails;%0A
-
 import org.s
@@ -1233,32 +1233,67 @@
 %0A%0A    @Override%0A
+    @Cacheable( value = %22message%22)%0A
     public boole
@@ -1688,32 +1688,67 @@
 %0A%0A    @Override%0A
+    @Cacheable( value = %22message%22)%0A
     public List%3C
@@ -2322,401 +2322,20 @@
 urn 
+ sort(
 result
-%0A                    .stream()%0A                    .sorted(%0A                            Comparator%0A                                    .comparing(%0A                                            Message ::getSendDate%0A                                    ))%0A                    .collect(%0A                            Collectors%0A                                    .toList()%0A                    
 );%0A 
@@ -3179,401 +3179,20 @@
 urn 
+ sort(
 result
-%0A                    .stream()%0A                    .sorted(%0A                            Comparator%0A                                    .comparing(%0A                                            Message ::getSendDate%0A                                    ))%0A                    .collect(%0A                            Collectors%0A                                    .toList()%0A                    
 );%0A 
@@ -3384,33 +3384,32 @@
 %E5%A4%B1%E8%B4%A5%22);%0A        %7D%0A
-%0A
     %7D%0A%0A    priva
@@ -3695,32 +3695,32 @@
 QDaoException %7B%0A
-
         return m
@@ -3779,24 +3779,465 @@
 al);%0A    %7D%0A%0A
+    private List%3CMessage%3E sort(List%3CMessage%3E messageses) %7B%0A        return messageses%0A                .stream()%0A                .sorted(%0A                        Comparator%0A                                .comparing(%0A                                        Message ::getSendDate%0A                                ))%0A                .collect(%0A                        Collectors%0A                                .toList()%0A                );%0A    %7D%0A%0A
     @Autowir

add cache