// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package com.dom_distiller.client;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Node;

import de.l3s.boilerpipe.BoilerpipeProcessingException;
import de.l3s.boilerpipe.document.TextBlock;
import de.l3s.boilerpipe.document.TextDocument;
import de.l3s.boilerpipe.extractors.CommonExtractors;
import de.l3s.boilerpipe.labels.DefaultLabels;
import de.l3s.boilerpipe.sax.BoilerpipeHTMLContentHandler;

import org.timepedia.exporter.client.Export;
import org.timepedia.exporter.client.Exportable;

import org.xml.sax.AttributesImpl;
import org.xml.sax.SAXException;

@Export()
public class ContentExtractor implements Exportable {
    static Logger logger = Logger.getLogger("DomDistiller");

    public static String extractContent() {
        BoilerpipeHTMLContentHandler htmlParser = new BoilerpipeHTMLContentHandler();
        List<Node> textNodes = null;

        try {
            htmlParser.startDocument();
            Element documentElement = Document.get().getDocumentElement();
            textNodes = DomToSaxParser.parse(documentElement, htmlParser);
            htmlParser.endDocument();
        } catch (SAXException e) {
            logger.warning("Parsing failed.");
            return "";
        }

        TextDocument document = htmlParser.toTextDocument();
        try {
            CommonExtractors.ARTICLE_EXTRACTOR.process(document);
        } catch (BoilerpipeProcessingException e) {
            logger.warning("Processing failed.");
            return "";
        }

        List<Integer> contentTextIndexes = new ArrayList<Integer>();
        for (TextBlock tb : document.getTextBlocks()) {
            if (!tb.hasLabel(DefaultLabels.TITLE)) {
                contentTextIndexes.addAll(tb.getContainedTextElements());
            }
        }
        Collections.sort(contentTextIndexes);

        // Boilerpipe's text node indexes start at 1.
        List<Node> contentNodes = new ArrayList<Node>(contentTextIndexes.size());
        for (Integer i : contentTextIndexes) {
            contentNodes.add(textNodes.get(i - 1));
        }

        List<Node> contentAndImages = RelevantImageFinder.findAndAddImages(
                contentNodes, Document.get().getDocumentElement());

        Node clonedSubtree = NodeListExpander.expand(contentAndImages).cloneSubtree();

        if (clonedSubtree.getNodeType() != Node.ELEMENT_NODE) {
            return "";
        }
        // TODO(cjhopman): this discards the top element and just returns its children. This might
        // break in some cases.
        return Element.as(clonedSubtree).getInnerHTML();
    }
}

@@ -305,24 +305,72 @@
 ng.Logger;%0A%0A
+import com.google.gwt.dom.client.AnchorElement;%0A
 import com.g
@@ -480,16 +480,59 @@
 nt.Node;
+%0Aimport com.google.gwt.dom.client.NodeList;
 %0A%0Aimport
@@ -2819,32 +2819,79 @@
 n %22%22;%0A        %7D%0A
+%0A        makeAllLinksAbsolute(clonedSubtree);%0A%0A
         // TODO(
@@ -3067,11 +3067,375 @@
 );%0A    %7D
+%0A%0A    private static void makeAllLinksAbsolute(Node rootNode) %7B%0A        Element root = Element.as(rootNode);%0A        NodeList%3CElement%3E allLinks = root.getElementsByTagName(%22A%22);%0A        for (int i = 0; i %3C allLinks.getLength(); i++) %7B%0A            AnchorElement link = AnchorElement.as(allLinks.getItem(i));%0A            link.setHref(link.getHref());%0A        %7D%0A    %7D
 %0A%7D%0A

make all links absolute