package jp.sourceforge.shovel.action.impl;

import static jp.sourceforge.shovel.SessionConst.*;
import static jp.sourceforge.shovel.MethodType.*;
import static jp.sourceforge.shovel.ViewType.*;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.seasar.framework.container.S2Container;

import jp.sourceforge.shovel.FormatType;
import jp.sourceforge.shovel.action.IFriendsAction;
import jp.sourceforge.shovel.annotation.Perform;
import jp.sourceforge.shovel.entity.IFriendship;
import jp.sourceforge.shovel.entity.IListRefine;
import jp.sourceforge.shovel.entity.IStatus;
import jp.sourceforge.shovel.entity.IUser;
import jp.sourceforge.shovel.exception.ApplicationException;
import jp.sourceforge.shovel.form.IFriendsForm;
import jp.sourceforge.shovel.service.IDirectoryService;
import jp.sourceforge.shovel.service.IShovelService;

public class FriendsActionImpl implements IFriendsAction {
    IFriendsForm actionForm_;
    HttpServletRequest request_;
    S2Container container_;
    
    @Perform(CSRF=false, login=true)
    public String perform() throws Exception {
        FormatType formatType = actionForm_.getFormatType();
        int page = actionForm_.getPage();
        int limit = actionForm_.getCount();
        String foreignKey = actionForm_.getForeignKey();
        long userId = actionForm_.getUserId();
        
        if (formatType.isHtml()) {
            IListRefine listRefine = (IListRefine)getSession().getAttribute(S_LIST_REFINE);
            if (listRefine == null || !listRefine.getViewType().isFriends()) {
                listRefine = (IListRefine)container_.getComponent(IListRefine.class);
                getSession().setAttribute(S_LIST_REFINE, listRefine);
            } else if (actionForm_.getMethodType() == PAGE) {
                listRefine.setPage(actionForm_.getPage());
            }
            listRefine.setViewType(actionForm_.isFollowers() ? FOLLOWERS : FRIENDS);
            
            page = listRefine.getPage();
            limit = 0;
        }
        
        IShovelService shovelService = getShovelService();
        IDirectoryService directoryService = shovelService.getDirectoryService();
        IUser user = null;
        if (foreignKey == null || foreignKey.length() <= 0) {
            user = directoryService.getLoginUser();
            foreignKey = user.getForeignKey();
        } else if (foreignKey.matches("^[0-9]+$")) {
            user = directoryService.getUser(userId);
        } else {
            user = directoryService.getUser(foreignKey);
        }
        
        IFriendship[] tmp;
        if (shovelService.isMobilePhone()) {
            tmp = shovelService.searchFriends(user.getUserId(), actionForm_.getKeyword(),
                    actionForm_.getSearchFriendsType(), page, limit);
        } else if (actionForm_.isFollowers()) {
            tmp = shovelService.getFollowers(foreignKey, true, page, limit);
        } else {
            boolean withFollower = formatType.isHtml() && (foreignKey == null || foreignKey.length() <= 0);
            tmp = shovelService.getFriends(foreignKey, withFollower, page, limit);
        }
        IFriendship[] friends = shovelService.prepareForView(tmp, limit, true);
        request_.setAttribute("friendships", friends);
        
        String forward = null;
        switch (formatType) {
        case HTML:
            if (friends != null && friends.length > 0) {
                request_.setAttribute("nextPage", tmp.length > friends.length);
            }
            
            shovelService.prepareForView(user);
            request_.setAttribute("user", user);
            
            if (shovelService.isMobilePhone()) {
                request_.setAttribute("keyword", actionForm_.getKeyword());
                request_.setAttribute("type", actionForm_.getSearchFriendsType());
                request_.setAttribute("page", page);
                forward = MOBILE;
            } else {
                forward = actionForm_.isPartial() ? PARTIAL : FULL;
            }
            break;
        case JSON:
        case XML:
            IStatus[] statuses;
            if (friends != null && friends.length > 0) {
                long[] userIds = new long[friends.length];
                int i = 0;
                for (IFriendship friend : friends) {
                    userIds[i++] = friend.getPassiveId();
                }
                statuses = shovelService.getRecents(userIds);
                shovelService.prepareForView(statuses, 0, true);
            } else {
                statuses = new IStatus[0];
            }
            Map<String, IStatus> statusMap = new HashMap<String, IStatus>();
            for (IStatus status : statuses) {
                long senderId = status.getSenderId();
                statusMap.put(String.valueOf(senderId), status);
            }
            request_.setAttribute("statuses", statusMap);
            
            forward = formatType.getId();
            break;
        default:
            throw new ApplicationException("");
        }
        
        return forward;
    }
    public void setFriendshipForm(IFriendsForm actionForm) {
        actionForm_ = actionForm;
    }
    public IShovelService getShovelService() {
        return (IShovelService)request_.getAttribute("shovelService");
    }
    public void setContainer(S2Container container) {
        container_ = container;
    }
    public void setRequest(HttpServletRequest request) {
        request_ = request;
    }
    HttpSession getSession() {
        return request_.getSession(true);
    }
}
