package page.tools.admin;

import java.io.IOException;
import java.io.File;

import org.wikiwebserver.core.WareHouse;
import org.wikiwebserver.handler.http.HTTPHandler;
import org.wikiwebserver.handler.http.HTTPOutputStream;
import org.wikiwebserver.handler.http.interfaces.HTTPResponder;

import page.tools.entity.Browser;
import page.tools.entity.User;
import page.tools.entity.NodeData;
import page.tools.entity.Order;

public class Cleanup implements HTTPResponder {
    
	// Note to self: ensure these do not wrap!!
    private static final long BROWSER_ABANDONMENT_TIME = 14l * 24 * 60 * 60 * 1000;
    private static final long NODE_ABANDONMENT_TIME = 28l * 24 * 60 * 60 * 1000;    
    private static final long ORDER_ABANDONMENT_TIME = 60 * 60 * 1000;
	
    public Object respond(HTTPHandler conn) throws IOException {
        
        conn.getResponse().getHeaders().set("Content-Type", "text/plain");
        conn.getResponse().getHeaders().set("Content-Encoding", "none");  
        
        WareHouse.getWikiMap("Statistics", "Referers").clear();
        WareHouse.getWikiMap("Statistics", "Keywords").clear();
                
        

        for (String orderId : Order.listIds()) {
        	if (!orderId.equals("Index")) {
        		processOrder(orderId, conn.getOutputStream());
        	}
        }
        

        for (String nodeId : NodeData.listIds()) {
        	if (!nodeId.equals("Index") && !nodeId.equals("local")) {
        		processNodeData(nodeId, conn.getOutputStream());
        	}
        } 
        
        for (String browserId : Browser.listIds()) {
        	if (!browserId.equals("Index")) {
        		processBrowser(browserId, conn.getOutputStream());
        	}
        }  

        cleanupUserDirectories(conn.getOutputStream());
        
        return null;
    }
    
    public void processBrowser(String browserId, HTTPOutputStream out) throws IOException {
        Browser b = Browser.getBrowserById(browserId);
        if (b != null) {
            long time = System.currentTimeMillis();
            Long lastAccess = (Long) b.get("lastRequestTime");
            out.write("Browser: " + b.getId());
            if (lastAccess != null) {
                String lastAccessString = WareHouse.formatStandardDate(lastAccess);
                out.write(", " + lastAccessString);
            }
            b.put("UserIDs", null);
            if (lastAccess == null || time > lastAccess.longValue() + BROWSER_ABANDONMENT_TIME) {
                out.write(" Abandoned");
                try {
                    b.clear();
                } catch (Throwable t) {
                    out.write(" " + t.getMessage());
                }                    
            }
            out.write("\r\n");

        } else {
            out.write("Isolated browser: " + browserId + "\r\n");
        }
    }
    
    public void processNodeData(String nodeId, HTTPOutputStream out) throws IOException {
        NodeData n = NodeData.getNodeDataById(nodeId);
        if (n != null) {
            long time = System.currentTimeMillis();
            Long lastAccess = (Long) n.get("lastRequestTime");
            out.write("Node: " + n.getId());
            if (lastAccess != null) {
                String lastAccessString = WareHouse.formatStandardDate(lastAccess);
                out.write(", " + lastAccessString);
            }
            if (lastAccess == null || time > lastAccess.longValue() + NODE_ABANDONMENT_TIME) {
                out.write(" Abandoned");
                try {
                    n.clear();
                } catch (Throwable t) {
                    out.write(" " + t.getMessage());
                }                    
            }
            out.write("\r\n");
        } else {
            out.write("Isolated node: " + nodeId + "\r\n");
        }
    }    
    
    public void processOrder(String orderId, HTTPOutputStream out) throws IOException {
        Order o = Order.getOrderById(orderId);
        if (o != null) {
            long time = System.currentTimeMillis();
            Long created = (Long) o.get("createdTime");
            if (created != null) {
                String lastAccessString = WareHouse.formatStandardDate(created);
                out.write("Order: " + o.getId() + ", " + lastAccessString);
                if (o.getPayment() == null) {
                    if (time > created + ORDER_ABANDONMENT_TIME) {
                        out.write(" Abandoned");
                        try {
                            o.clear();
                        } catch (Throwable t) {
                            out.write(" " + t.getMessage());
                        }
                    } else {
                        out.write(" Pending");
                    }
                }
                if (o.isTest()) {
                    out.write(" Test");
                    if (time > created + ORDER_ABANDONMENT_TIME) {
                        try {
                            o.getPayment().clear();
                            o.clear();
                        } catch (Throwable t) {
                            out.write(" " + t.getMessage());
                        }
                    }
                }
                out.write("\r\n");
            }
        } else {
            out.write("Isolated order: " + orderId + "\r\n");
        }
    }    

   
private void cleanupUserDirectories(HTTPOutputStream out) throws IOException {     
  File dir = new File("user");
  out.write("User directories: " + dir.listFiles().length + "\r\n");

  for (File file : dir.listFiles()) {
    String name = file.getName();

    if (name.endsWith(".abandoned")) {
      name = name.substring(0, name.indexOf("."));
      file.renameTo(new File(dir, name));
    }

    if (!name.startsWith(".") && User.getUserById(name.substring(1)) == null) {
      out.write("Abandoned dir: " + file.toString() + "\r\n");
      file.renameTo(new File(dir, name + ".abandoned"));
    }
  }
}
}
