package page.tools.stats;

import java.io.IOException;
import java.util.Map;
import java.util.TreeSet;

import org.wikiwebserver.core.WareHouse;
import org.wikiwebserver.core.WikiMap;
import org.wikiwebserver.handler.http.FormData;
import org.wikiwebserver.handler.http.HTTPHandler;
import org.wikiwebserver.handler.http.interfaces.CacheableHTTPResponse;
import org.wikiwebserver.handler.http.interfaces.HTTPResponder;
import org.wikiwebserver.util.comparator.DescendingEntryValueComparator;

import page.config.SiteMonitor;
import page.tools.entity.Comment;
import page.tools.entity.NodeData;
import page.tools.entity.Payment;
import page.tools.entity.User;
import page.tools.xml.RSSChannel;
import page.tools.xml.RSSItem;
import page.tools.xml.RSSResponder;

public class RSSStats implements HTTPResponder, CacheableHTTPResponse {
    
    public static final int MAX_ITEMS = 25;
    
    private final int TYPE_USER = 0, TYPE_NODE = 1, TYPE_PAYMENT = 2, TYPE_COMMENT = 3;  
    
    public Object respond(HTTPHandler conn) throws IOException {
        
        this.serviceAddress = conn.getServiceAddress();
        
        String name = "UserAccessTimes";
        
        FormData formData = conn.getRequest().getFormData();
        if (formData != null) {
            name = formData.getFirst("name");
        }
        
        String title = null;
        String link = WareHouse.getUrlPathForClass(Status.class);
        String description = null;
        if (name.equals("UserAccessTimes")) {
            title = "Recent WikiWebServer User Accesses";
            description = "Feed of recent accesses by registered users";
        } else if (name.equals("UserRegistrationTimes")) {
            title = "Recent WikiWebServer Registrations";
            description = "Feed of recent user registrations";      
        } else if (name.equals("NewNodeTimes")) {
            title = "New nodes linked to WikiWebServer";
            description = "Feed of new nodes";                
        } else if (name.equals("PaymentTimes")) {
            title = "Recent WikiWebServer Contributions";
            description = "Feed of recent contributions";            
        } else if (name.equals("CommentTimes")) {
            title = "Recent WikiWebServer Comments";
            description = "Feed of recent comments";            
        }
        
        RSSChannel channel = new RSSChannel(name, title, link, description);
        
        if (name.equals("UserAccessTimes")) {
            addItems(channel, TYPE_USER, "User access", name, MAX_ITEMS);
        } else if (name.equals("UserRegistrationTimes")) {
            addItems(channel, TYPE_USER, "User registration", name, MAX_ITEMS);
        } else if (name.equals("NewNodeTimes")) {
            addItems(channel, TYPE_NODE, "New node", name, MAX_ITEMS);            
        } else if (name.equals("PaymentTimes")) {
            addItems(channel, TYPE_PAYMENT, "Payment", name, MAX_ITEMS);
        } else if (name.equals("CommentTimes")) {
            addItems(channel, TYPE_COMMENT, "Comment", name, MAX_ITEMS);
        }
                
        return new RSSResponder(channel);
    }   
    
    
    private void addItems(RSSChannel channel, int type, String action, String store, int limit) {
        
        TreeSet<Map.Entry<String, Object>> sortedSet 
            = new TreeSet<Map.Entry<String, Object>>(
                    new DescendingEntryValueComparator<String, Object>());

        Map<String, Object> dataStore = (WikiMap) SiteMonitor.getStatistic(store);
        if (dataStore == null) return;
        
        for (Map.Entry<String, Object> entry : dataStore.entrySet()) {
            sortedSet.add(entry);
        }

        
        int count = 0;
        for (Map.Entry<String, Object> entry: sortedSet) {
            Object value = entry.getValue();
            String id = entry.getKey();
            long time = ((Long) value).longValue();            
            String displayTime = WareHouse.formatStandardDate(time);
            
            
            
            if (type == TYPE_USER) {
                User u = User.getUserById(id);
                if (u != null) {
                    String title = action + " by " + u.getEmail();
                    String description = action + " by " + u.getEmail() + " at " + displayTime;
                    RSSItem newItem = new RSSItem(title, description);
                    String link = serviceAddress + WareHouse.getUrlPathForClass(BrowserInfo.class) + "?userID=" + u.getId();
                    newItem.setLink(link);
                    newItem.setPubDate(time);
                    channel.addItem(newItem);
                }
            }
            else if (type == TYPE_NODE) {
                NodeData n = NodeData.getNodeDataById(id);
                if (n != null) {
                	String name = n.getName();
                	if (name == null) name = "Unknown";
   
                	String title = action + " connected named " + name;
                    String description = action + " connected named " + name + " at " + displayTime;
                    RSSItem newItem = new RSSItem(title, description);
                    String link = serviceAddress + WareHouse.getUrlPathForClass(NodeInfo.class) + "?nodeID=" + n.getId();
                    newItem.setLink(link);
                    newItem.setPubDate(time);
                    channel.addItem(newItem);
                }
            }            
            else if (type == TYPE_PAYMENT) {
                Payment p = Payment.getPaymentById(id);
                if (p != null) {
                    String email = p.getOrder().getPayer().getEmail();
                    String title = action + " by " + email;
                    String description = action + " of " + p.getAmount() + " by " + email + 
                                         " made at " + displayTime;
                    
                    RSSItem newItem = new RSSItem(title, description);
                    String link = serviceAddress + WareHouse.getUrlPathForClass(BrowserInfo.class) + 
                                  "?userID=" + p.getOrder().getPayer().getId();
                    newItem.setLink(link);
                    newItem.setPubDate(time);
                    channel.addItem(newItem);
                }
            }
            else if (type == TYPE_COMMENT) {
                Comment c = Comment.getCommentById(id);
                if (c != null) {
                    String email = c.getAuthor().getEmail();
                    String title = action + " by " + email + " at " + displayTime;
                    String description = c.getText();                   
                    
                    RSSItem newItem = new RSSItem(title, description);
                    String link = serviceAddress + WareHouse.getUrlPathForClass(BrowserInfo.class) + 
                                  "?userID=" + c.getAuthor().getId();
                    newItem.setLink(link);
                    newItem.setPubDate(time);
                    channel.addItem(newItem);
                }
            }            
            
            if (limit != -1 && ++count > limit) break;            
        } 
    }      
    
    private String serviceAddress;

    public String getCacheKey() {
        return String.valueOf(System.currentTimeMillis() / 1000);
    }


    public long getExpireTime() {
        return System.currentTimeMillis() + 1000;
    }


    public void init(HTTPHandler conn) throws IOException {
        conn.getResponse().getHeaders().set("Content-Type", "text/xml");
    }
}

