package page.example;

import java.io.*;
import java.util.*;

import org.wikiwebserver.core.WareHouse;
import org.wikiwebserver.core.WikiMap;
import org.wikiwebserver.handler.http.interfaces.*;
import page.config.SiteTemplatedPage;


public class LineCount extends SiteTemplatedPage implements HTTPResponder {
    
    public static final long CACHE_PERIOD = 24*60*60*1000;
    public static final char END_OF_LINE_CHAR = '\n'; // Previously was semicolon
    
    private ArrayList<File> fileList;
    
    public void setFile(File file) {
        this.fileList = new ArrayList<File>();
        if (file == null) {
            populate(new File("org/wikiwebserver/"), fileList);
            populate(new File("page/"), fileList);
        }
        else {
            if (file.isDirectory()) {
                populate(file, fileList);
            } 
            else fileList.add(file);           
        }
    }
    
    public String getNumLines() {
        
        if (fileList == null) {
            setFile(null);

            long time = System.currentTimeMillis();        
            Long cacheTime = (Long) getWikiMap().get("cacheTime");
            
            if (cacheTime == null || time > cacheTime.longValue() + CACHE_PERIOD) {  
                
                cacheTime = new Long(time);
                
                int lineCount = getLineCount(fileList);
                getWikiMap().put("lineCountCache", WareHouse.formatNumber(lineCount));
                getWikiMap().put("cacheTime", cacheTime);
            }  
            
            return getWikiMap().get("lineCountCache").toString();
        }
        else {
            return WareHouse.formatNumber(getLineCount(fileList));
        }
    }
	
    public void generate() {
        
        String description = "This page counts the total number of lines of Java code in WikiWebServer";
        
        setTitle("Lines of code - WikiWebServer.org");
        setDescription(description);        
        
        String lineCount = getNumLines();
        Long cacheTime = (Long) getWikiMap().get("cacheTime");
       
        append("<h1>Line count</h1>" +
               "<p>" + description + "</p>" +
               "<p>Line count: " + lineCount +
               "<p>Lines last counted on " + WareHouse.formatStandardDate(cacheTime) + " </p>");
        
        
    }  
    
    private int getLineCount(ArrayList<File> list) {

        int count = 0;
        for (File file : list) {
            count += getLineCount(file);
        }
        return count;
    }
    
    private int getLineCount(File file) {

        try {
            return countLines(new FileInputStream(file));
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        return 0;
    }   
    
    private int countLines(InputStream in) throws IOException {
        int count = 0;
        int i = in.read();
        while (i != -1) {
            if (i == END_OF_LINE_CHAR) count++;
            i = in.read();
        }
        in.close();
        return count;
    }    
    
    private void populate(File dir, ArrayList<File> list) {
        File[] files = dir.listFiles();
        if (files == null) return;
        
        for (File file : files) {
            try {
                if (file.isDirectory()) {
                    populate(file, list);
                }
                String type = WareHouse.getContentType(file);
                if (type != null && type.equals("text/java")) {
                    list.add(file);
                }
            } catch (SecurityException ex) {
                // Thrown by org.wikiwebserver.core.SecurityMan
            }
        }
    }    
    
    
    private static WikiMap getWikiMap() {
        WikiMap map = WareHouse.getWikiMap("LineCount");
        if (map == null) map = WareHouse.initWikiMap("LineCount");
        return map;
    }     
}
