package jp.sourceforge.shovel.action.impl;

import static jp.sourceforge.shovel.SessionConst.*;
import static jp.sourceforge.shovel.SortType.*;

import java.io.InputStreamReader;
import java.io.Reader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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

import org.apache.struts.upload.FormFile;

import au.com.bytecode.opencsv.bean.ColumnPositionMappingStrategy;
import au.com.bytecode.opencsv.bean.CsvToBean;

import jp.sourceforge.shovel.SortOrderType;
import jp.sourceforge.shovel.action.IImportAccountsAction;
import jp.sourceforge.shovel.annotation.Perform;
import jp.sourceforge.shovel.entity.IListRefine;
import jp.sourceforge.shovel.entity.IUser;
import jp.sourceforge.shovel.entity.impl.UserImpl;
import jp.sourceforge.shovel.exception.ApplicationException;
import jp.sourceforge.shovel.form.IImportAccountsForm;
import jp.sourceforge.shovel.service.IDirectoryService;
import jp.sourceforge.shovel.service.IShovelService;

public class ImportAccountsActionImpl implements IImportAccountsAction {
    IImportAccountsForm actionForm_;
    HttpServletRequest request_;
    static final Pattern pattern_ = Pattern.compile("\\s*(\")?(.*)\\1?");
    
    String trimQuote(String data) {
        Matcher matcher = pattern_.matcher(data);
        if (matcher.find()) {
            data = matcher.group(2);
        }
        return data.trim();
    }
    
    @Perform(CSRF=true, administrator=true)
    public String perform() throws Exception {
        FormFile file = actionForm_.getFile();
        if (file == null) {
            throw new ApplicationException("");
        }
        String charSet = actionForm_.getCharSet();
        Reader reader = new InputStreamReader(file.getInputStream(), charSet);
        
        ColumnPositionMappingStrategy mapper = new ColumnPositionMappingStrategy();
        mapper.setType(UserImpl.class);
        String[] columns = new String[] {"displayName", "foreignKey", "password",
                "email", "location"};
        mapper.setColumnMapping(columns);
        CsvToBean csv = new CsvToBean();
        List<?> userList = csv.parse(mapper, reader);
        Map<String, IUser> userMap = new HashMap<String, IUser>();
        
        String[] foreignKeys = new String[userList.size()];
        int i = 0;
        for (Object o : userList) {
            IUser user = (IUser)o;
            user.setDisplayName(trimQuote(user.getDisplayName()));
            user.setForeignKey(trimQuote(user.getForeignKey()));
            user.setPassword(trimQuote(user.getPassword()));
            user.setEmail(trimQuote(user.getEmail()));
            user.setLocation(trimQuote(user.getLocation()));
            foreignKeys[i++] = user.getForeignKey();
            userMap.put(user.getForeignKey(), user);
        }
        
        IShovelService shovelService = getShovelService();
        IDirectoryService directoryService = shovelService.getDirectoryService();
        IUser[] users = directoryService.getUsers(foreignKeys);
        if (users != null && users.length > 0) {
            for (IUser user : users) {
                IUser tmp = userMap.get(user.getForeignKey());
                tmp.setUserId(user.getUserId());
            }
        }
        
        for (Object o : userList) {
            IUser user = (IUser)o;
            String displayName = user.getDisplayName();
            String foreignKey = user.getForeignKey();
            String password = user.getPassword();
            String email = user.getEmail();
            String location = user.getLocation();
            if (user.getUserId() > 0) {
                directoryService.updateUserFromImportCsv(user);
            } else {
                directoryService.createUser(displayName, foreignKey,password,
                        email, null, location, null, "", false, false);
            }
        }
        
        IListRefine listRefine = (IListRefine)getSession().getAttribute(S_LIST_REFINE);
        SortOrderType sortOrderType = listRefine.getSortOrderType();
        //0頁目に戻す
        users = directoryService.getUsers(USER_ID, sortOrderType, 0);
        if (users != null && users.length > 0) {
            IUser[] tmp = shovelService.prepareForView(users, 0);
            request_.setAttribute("nextPage", tmp.length > users.length);
            users = tmp;
        }
        request_.setAttribute("users", users);
        
        request_.setAttribute("callback", "window.parent.shovel.controller.onChangeConfig($('#content').html());");
        request_.setAttribute("template", "system/accounts.ftl");
        
        return SUCCESS;
    }
    public void setImportAccountsForm(IImportAccountsForm actionForm) {
        actionForm_ = actionForm;
    }
    public void setRequest(HttpServletRequest request) {
        request_ = request;
    }
    HttpSession getSession() {
        return request_.getSession(true);
    }
    public IShovelService getShovelService() {
        return (IShovelService)request_.getAttribute("shovelService");
    }
}
