/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.camel.manual;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import org.ccil.cowan.tagsoup.Parser;
import org.ccil.cowan.tagsoup.XMLWriter;

public class ManualGenerator {

    String page;
    String output;
    String head;
    String version;
    String targetDir;
    
    public ManualGenerator(String[] args) {
        page = args[0];
        output = args[1];
        version = args[2];
        head = args[3];
        targetDir = args[4];
    }
    
    public void run() {
        try {
            if (doGenerate()) {
                String content = grabBodyContent();
                storeHTMLFile(content);
            }
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    
    private void storeHTMLFile(String content) throws IOException {
        String replaceToken = "<h3 id=\"replaceme\">.*</h3>";
        String replaceValue = "<h3>Version " + version + "</h3>";
        
        File outFile = new File(output);
        outFile.getParentFile().mkdirs();
        PrintWriter out = new PrintWriter(new BufferedOutputStream(new FileOutputStream(outFile)));
        out.println("<html>");
        out.println("<head>");
        if (head != null) {
            out.println(head);
        }
        out.println("</head>");
        
        if (replaceToken != null && replaceValue != null) {
            content = content.replaceAll(replaceToken, replaceValue);
        }
        
        out.print("<body>");
        out.print(content);
        out.println("</body>");
        out.close();
    }
    private boolean doGenerate() throws MalformedURLException, IOException {
        URL url = new URL(page);
        File file = new File(targetDir, ".manualCache-" + url.getFile().substring(1));
        if (file.exists()) {
            HttpURLConnection con = (HttpURLConnection)url.openConnection();
            con.setRequestMethod("HEAD");
            long date = con.getLastModified();
            
            FileReader reader = new FileReader(file);
            char chars[] = new char[1000];
            int i = reader.read(chars);
            reader.close();

            long lastDate = Long.parseLong(new String(chars, 0, i).trim());
            if (date <= lastDate) {
                return false;
            }
        }
        return true;
    }
    private String grabBodyContent() throws MalformedURLException, IOException {
        URL url = new URL(page);
        File file = new File(targetDir, ".manualCache-" + url.getFile().substring(1));
        
        try {
            HttpURLConnection con = (HttpURLConnection)url.openConnection();
            XMLReader parser = new Parser();
            parser.setFeature(Parser.namespacesFeature, false);
            parser.setFeature(Parser.namespacePrefixesFeature, false);
            parser.setProperty(Parser.schemaProperty, new org.ccil.cowan.tagsoup.HTMLSchema() {
                {
                    //problem with nested lists that the confluence {toc} macro creates
                    elementType("ul", M_LI, M_BLOCK | M_LI, 0);
                }
            });
            
            StringWriter w = new StringWriter();
            XMLWriter xmlWriter = new XMLWriter(w) {
                int inDiv = Integer.MAX_VALUE;
                int count;
                public void characters(char ch[], int start, int len)
                    throws SAXException {
                    if (inDiv <= count) {
                        super.characters(ch, start, len);
                    }
                }
                public void startElement(String uri, String localName, String qName, Attributes atts)
                    throws SAXException {
                    count++;
                    if ("div".equalsIgnoreCase(qName)
                        && "wiki-content maincontent".equalsIgnoreCase(atts.getValue("class"))) {
                        inDiv = count;
                    }
                    if (inDiv <= count) {
                        super.startElement(uri, localName, qName, atts);
                    }
                }
                public void endElement(String uri, String localName, String qName) throws SAXException {
                    if (inDiv <= count) {
                        super.endElement(uri, localName, qName);
                    }
                    count--;
                    if (inDiv > count) {
                        inDiv = Integer.MAX_VALUE;
                    }
                }
            };
            xmlWriter.setOutputProperty(XMLWriter.OMIT_XML_DECLARATION, "yes");
            xmlWriter.setOutputProperty(XMLWriter.METHOD, "html");
            parser.setContentHandler(xmlWriter);
            long date = con.getLastModified();
            parser.parse(new InputSource(new BufferedInputStream(con.getInputStream())));

            
            FileWriter writer = new FileWriter(file);
            writer.write(Long.toString(date));
            writer.close();
            return w.toString();
        } catch (Throwable e) {
            e.printStackTrace();
            throw new RuntimeException("Failed", e);
        }
    }
    

    /**
     * @param args
     */
    public static void main(String[] args) {
        /*args = new String[] {
            "http://camel.apache.org/book-in-one-page.html",
            "/tmp/foo.html",
            "1.0",
            ""
        };*/
        new ManualGenerator(args).run();
    }

}
