/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  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.  For additional information regarding
 * copyright in this work, please see the NOTICE file in the top level
 * directory of this distribution.
 */

package org.apache.roller.weblogger.util;

import java.io.IOException;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.util.RollerConstants;
import org.apache.roller.weblogger.WebloggerException;
import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.roller.weblogger.pojos.WeblogEntry;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;


/**
 * Represents a trackback request.
 */
public class Trackback {
    
    private static final Log LOG = LogFactory.getLog(Trackback.class);
    
    private final WeblogEntry entry;
    private final String trackbackURL;
    
    
    public Trackback(WeblogEntry tEntry, String tURL)
            throws TrackbackNotAllowedException {
        
        // Make sure trackback to URL is allowed
        boolean allowTrackback = true;
        String allowedURLs = WebloggerConfig.getProperty("trackback.allowedURLs");
        if (!StringUtils.isEmpty(allowedURLs)) {
            // in the case that the administrator has enabled trackbacks
            // for only specific URLs, set it to false by default
            allowTrackback = false;
            String[] splitURLs = allowedURLs.split("\\|\\|");
            for (int i=0; i < splitURLs.length; i++) {
                Matcher m = Pattern.compile(splitURLs[i]).matcher(tURL);
                if (m.matches()) {
                    allowTrackback = true;
                    break;
                }
            }
        }
        
        if(!allowTrackback) {
            throw new TrackbackNotAllowedException(tURL);
        } else {
            // test url
            try {
                new URL(tURL);
            } catch(MalformedURLException ex) {
                // bad url
                throw new IllegalArgumentException("bad url: "+tURL);
            }
            
            entry = tEntry;
            trackbackURL = tURL;
        }
        
    }
    
    
    /**
     * Sends trackback from entry to remote URL.
     * See Trackback spec for details: http://www.sixapart.com/pronet/docs/trackback_spec
     */
    public RollerMessages send() throws WebloggerException {
        
        RollerMessages messages = new RollerMessages();
        
        LOG.debug("Sending trackback to url - " + trackbackURL);
        
        // Construct data
        String title = entry.getTitle();
        String excerpt = StringUtils.left( Utilities.removeHTML(entry.getDisplayContent()),
                RollerConstants.TEXTWIDTH_255);
        String url = entry.getPermalink();
        String blog_name = entry.getWebsite().getName();
        
        // build trackback post parameters as query string
        Map params = new HashMap();
        params.put("title", URLUtilities.encode(title));
        params.put("excerpt", URLUtilities.encode(excerpt));
        params.put("url", URLUtilities.encode(url));
        params.put("blog_name", URLUtilities.encode(blog_name));
        String queryString = URLUtilities.getQueryString(params);
        
        LOG.debug("query string - " + queryString);
        
        // prepare http request
        HttpClient client = new HttpClient();
        client.setConnectionTimeout(45 * RollerConstants.SEC_IN_MS);
        HttpMethod method = new PostMethod(trackbackURL);
        method.setQueryString(queryString);
        
        try {
            // execute trackback
            int statusCode = client.executeMethod(method);
            
            // read response
            byte[] response = method.getResponseBody();
            String responseString = Utilities.escapeHTML(new String(response, "UTF-8"));
            
            LOG.debug("result = " + statusCode + " " + method.getStatusText());
            LOG.debug("response:\n" + responseString);
            
            if(statusCode == HttpStatus.SC_OK) {
                // trackback request succeeded, message will give details
                try {
                    messages = parseTrackbackResponse(new String(response, "UTF-8"), messages);
                } catch (Exception e) {
                    // Cannot parse response, indicates failure
                    messages.addError("weblogEdit.trackbackErrorParsing", responseString);
                }
            } else if(statusCode == HttpStatus.SC_NOT_FOUND) {
                // 404, invalid trackback url
                messages.addError("weblogEdit.trackbackError404");
            } else {
                // some other kind of error with url, like 500, 403, etc
                // just provide a generic error message and give the http response text
                messages.addError("weblogEdit.trackbackErrorResponse",
                        new String[] {""+statusCode, method.getStatusText()});
            }
            
        } catch (IOException e) {
            // some kind of transport error sending trackback post
            LOG.debug("Error sending trackback", e);
            messages.addError("weblogEdit.trackbackErrorTransport");
        } finally {
            // release used connection
            method.releaseConnection();
        }
        
        return messages;
    }
    
    
    /**
     * Parse XML returned from trackback POST, returns error or success message
     * in RollerMessages object.
     */
    private RollerMessages parseTrackbackResponse(String response, RollerMessages messages) 
            throws JDOMException, IOException {
        
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(
                new StringReader(StringEscapeUtils.unescapeHtml4(response)));
        Element root = doc.getRootElement();
        
        if ("response".equals(root.getName())) {
            int code = -99;
            try {
                code = Integer.parseInt(root.getChildText("error"));
            } catch (NumberFormatException ignoredByDesign) {}
            
            String message = root.getChildText("message");
            if (code != 0) {
                messages.addError("weblogEdit.trackbackFailure", Utilities.removeHTML(message));
            } else {
                messages.addMessage("weblogEdit.trackbackSuccess");
            }
        } else {
            messages.addError("weblogEdit.trackbackErrorParsing", Utilities.removeHTML(response));
        }
        
        return messages;
    }
    
}
