/*
 * 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.any23.extractor.html.microformats2;

import org.apache.any23.extractor.ExtractionException;
import org.apache.any23.extractor.ExtractionResult;
import org.apache.any23.extractor.ExtractorDescription;
import org.apache.any23.extractor.TagSoupExtractionResult;
import org.apache.any23.extractor.html.microformats2.annotations.Includes;
import org.apache.any23.vocab.VCard;
import org.eclipse.rdf4j.model.BNode;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.w3c.dom.Node;
import org.apache.any23.extractor.html.EntityBasedMicroformatExtractor;
import org.apache.any23.extractor.html.HTMLDocument;

/**
 * Extractor for the <a href="http://microformats.org/wiki/h-adr">h-adr</a>
 * microformat.
 *
 * @author Nisala Nirmana
 */
@Includes( extractors = HGeoExtractor.class )
public class HAdrExtractor extends EntityBasedMicroformatExtractor {

    private static final VCard vVCARD = VCard.getInstance();

    private static final String[] addressFields = {
            "street-address",
            "extended-address",
            "locality",
            "region",
            "postal-code",
            "country-name",
            "geo"
    };

    private static final String[] geoFields = {
            "latitude",
            "longitude",
            "altitude"
    };

    protected String getBaseClassName() {
        return Microformats2Prefixes.CLASS_PREFIX+"adr";
    }

    @Override
    protected void resetExtractor() {
        // Empty.
    }

    protected boolean extractEntity(Node node, ExtractionResult out) throws ExtractionException {
        if (null == node) return false;
        final HTMLDocument document = new HTMLDocument(node);
        BNode adr = getBlankNodeFor(node);
        out.writeTriple(adr, RDF.TYPE, vVCARD.Address);
        final String extractorName = getDescription().getExtractorName();
        for (String field : addressFields) {
            HTMLDocument.TextField[] values = document.getPluralTextField(Microformats2Prefixes.PROPERTY_PREFIX+field);
            for (HTMLDocument.TextField val : values) {
               if(!field.equals("geo")) {
                        conditionallyAddStringProperty(
                                val.source(),
                                adr, vVCARD.getProperty(field), val.value()
                        );
               }else {
                   String[] composed = val.value().split(";");
                   for(int counter=0;counter<composed.length;counter++){
                       conditionallyAddStringProperty(
                               val.source(),
                               adr, vVCARD.getProperty(geoFields[counter]), composed[counter]
                       );

                   }
               }
            }
        }
        addGeoAsUrlResource(adr,document);
        final TagSoupExtractionResult tser = (TagSoupExtractionResult) getCurrentExtractionResult();
        tser.addResourceRoot( document.getPathToLocalRoot(), adr, this.getClass());
        return true;
    }

    private void addGeoAsUrlResource(Resource card,HTMLDocument document) throws ExtractionException {
        HTMLDocument.TextField[] links = document.getPluralUrlField(Microformats2Prefixes.URL_PROPERTY_PREFIX+"geo");
        for (HTMLDocument.TextField link : links) {
            conditionallyAddResourceProperty(card, vVCARD.geo, getHTMLDocument().resolveIRI(link.value()));
        }
    }

    @Override
    public ExtractorDescription getDescription() {
        return HAdrExtractorFactory.getDescriptionInstance();
    }

}
