/*
 * Copyright 2006 Wyona
 */

package org.wyona.yanel.impl.resources;

import org.wyona.yanel.core.Resource;
import org.wyona.yanel.core.api.attributes.ViewableV2;
import org.wyona.yanel.core.api.attributes.ModifiableV2;
import org.wyona.yanel.core.attributes.viewable.View;
import org.wyona.yanel.core.attributes.viewable.ViewDescriptor;

import org.wyona.yanel.impl.resources.CalendarEvent;

import org.apache.log4j.Category;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;

/**
 *
 */
public class CalendarResource extends Resource implements ViewableV2, ModifiableV2 {

    private static Category log = Category.getInstance(CalendarResource.class);

    /**
     *
     */
    public CalendarResource() {
    }

    /**
     *
     */
    public long getSize() throws Exception {
        log.warn("Not implemented yet!");
        return -1;
    }

    /**
     *
     */
    public boolean exists() throws Exception {
        log.warn("Not implemented yet!");
        return false;
    }

    /**
     * Generate view
     * @param viewId xml, ics, xhtml
     */
    public View getView(String viewId) throws Exception {
        String categories = getRTI().getProperty("categories");
        String classes = getRTI().getProperty("classes");
        String userIds = getRTI().getProperty("user-ids");
        log.error("DEBUG: " + categories + " " + classes + " " + userIds);

        org.wyona.yarep.core.Repository dataRepo = getRealm().getRepository();
        String eventsPath = getRTI().getProperty("events-path");
        if (eventsPath == null) {
            eventsPath = getPath().toString();
        }
        org.wyona.yarep.core.Path[] children = dataRepo.getChildren(new org.wyona.yarep.core.Path(eventsPath));
        //org.wyona.yarep.core.Path[] children = dataRepo.search("categories", categories);

        StringBuffer calendar = new StringBuffer("<?xml version=\"1.0\"?>\n<calendar>");
        for (int i = 0; i < children.length; i++) {
            if (dataRepo.isResource(children[i])) {
                InputStream in = dataRepo.getInputStream(children[i]);
                java.io.ByteArrayOutputStream baos  = new java.io.ByteArrayOutputStream();
                //StringBuffer event = new StringBuffer();
            
                byte[] buffer = new byte[8192];
                int bytesRead;
                while ((bytesRead = in.read(buffer)) != -1) {
                    //event.append(new String(buffer));
                    baos.write(buffer, 0, bytesRead);
                }

                String event = baos.toString();
                int endOfProcessingInstruction = event.indexOf("?>");
                if (endOfProcessingInstruction > 0) {
                    calendar.append(event.toString().substring(endOfProcessingInstruction + 2));
                } else {
                    log.error("No processing instruction: " + children[i]);            
                }
            }
        }
        calendar.append("</calendar>");

        if(viewId != null && viewId.equals("xml")) {
            //response.getOutputStream();

            View view = new View();
            //view.setResponse(false);
	    view.setMimeType("application/xml");
	    view.setInputStream(new java.io.StringBufferInputStream(calendar.toString()));
            return view;
        } else {
            String xslt = getRTD().getConfigFile().getParent() + File.separator + "xslt" + File.separator + "xml2ics.xsl";
            java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
            try {
                Transformer transformer = TransformerFactory.newInstance().newTransformer(new StreamSource(new File(xslt)));
		transformer.transform(new StreamSource(new java.io.StringBufferInputStream(calendar.toString())), new StreamResult(out));
            } catch(Exception e) {
                log.error(e.getMessage(), e);
            }

            //response.getOutputStream();

            View view = new View();
            //view.setResponse(false);
            String mimeType = getRTI().getProperty("mime-type");
            if (mimeType != null) {
	        view.setMimeType(mimeType);
	    } else {
	        view.setMimeType("text/calendar");
            }
	    view.setInputStream(new java.io.ByteArrayInputStream(out.toByteArray()));
            return view;
        }
    }

    /**
     *
     */
    public ViewDescriptor[] getViewDescriptors() {
        log.warn("Not implemented yet!");
        return null;
    }

    /**
     *
     */
    public boolean delete() throws Exception {
        log.warn("Not implemented yet!");
        return false;
    }

    /**
     *
     */
    public long getLastModified() throws Exception {
        log.warn("Not implemented yet!");
        return -1;
    }

    /**
     * Parse ICS and write events as XML into repository
     */
    public void write(InputStream in) throws Exception {
        log.warn("Not implemented yet!");
        log.warn("TODO: Parse ICS and write events as XML into repository ...");
        java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(in));
        String line;
        CalendarEvent event = null;
        while ((line = br.readLine()) != null) {
            if (line.startsWith("BEGIN:VEVENT")) {
                event = new CalendarEvent();
            } else if (line.startsWith("END:VEVENT")) {
                log.error("DEBUG: Write event " + event);
                event = null;
            } else if (line.startsWith("UID:")) {
                if (event != null) event.setUID(line.split(":")[1]);
            } else if (line.startsWith("SUMMARY:")) {
                if (event != null) event.setSummary(line.split(":")[1]);
            } else {
                log.warn("Not implemented yet: " + line);
            }
        }
    }

    /**
     *
     */
    public OutputStream getOutputStream() throws Exception {
        log.warn("Do not use this method but rather write(InputStream)!");
        return null;
        //return getRealm().getRepository().getOutputStream(new org.wyona.yarep.core.Path("/calendarTODO.ics"));
    }

    /**
     *
     */
    public InputStream getInputStream() throws Exception {
        log.warn("Not implemented yet!");
        return null;
    }

    /**
     *
     */
    public Reader getReader() throws Exception {
        log.warn("Not implemented yet!");
        return null;
    }

    /**
     *
     */
    public Writer getWriter() throws Exception {
        log.warn("Not implemented yet!");
        return null;
    }
}

@@ -5698,90 +5698,209 @@
 vent
-);%0A                event = null;%0A            %7D else if (line.startsWith(%22UID:%22)) %7B
+.getUID() + %22, %22 + event.toXML());%0A                Writer out = getRealm().getRepository().getWriter(new org.wyona.yarep.core.Path(getRTI().getProperty(%22events-path%22) + %22/%22 + event.getUID() + %22.xml%22));
 %0A   
@@ -5916,185 +5916,193 @@
     
-if (event != null) event.setUID(line.split(%22:%22)%5B1%5D);%0A            %7D else if (line.startsWith(%22SUMMARY:%22)) %7B%0A                if (event != null) event.setSummary(line.split(%22:%22)%5B1%5D
+out.write(event.toXML());%0A                out.close();%0A                event = null;%0A            %7D else %7B%0A                if (event != null) %7B%0A                    event.setProperty(line
 );%0A 
@@ -6104,32 +6104,36 @@
 e);%0A            
+    
 %7D else %7B%0A       
@@ -6117,32 +6117,36 @@
        %7D else %7B%0A
+    
                 
@@ -6183,24 +6183,42 @@
  %22 + line);%0A
+                %7D%0A
             

write data