/*
 * 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.business.pings;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.weblogger.config.PingConfig;
import org.apache.roller.weblogger.pojos.PingTarget;
import org.apache.roller.weblogger.pojos.Weblog;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Utility for sending a weblog update ping.
 *
 * This implements the <code>WeblogUpdates.ping<code> XML-RPC call described at
 * <a href="http://www.xmlrpc.com/weblogsCom">www.xmlrpc.com</a>
 * as well as some variants required to interoperate with certain
 * buggy but popular ping targets.
 *
 *
 * @author <a href="mailto:anil@busybuddha.org">Anil Gangolli</a>
 * @author llavandowska (for code refactored from the now-defunct <code>RollerXmlRpcClient</code>)
 */
public final class WeblogUpdatePinger {
    public static final Log LOGGER = LogFactory.getLog(WeblogUpdatePinger.class);

    /**
     * Conveys a ping result.
     */
    public static class PingResult {
        boolean error;
        String message;

        public PingResult(Boolean error, String message) {
            this.error = error != null && error;
            this.message = message != null ? message : "";
        }

        public boolean isError() {
            return error;
        }

        public void setError(boolean error) {
            this.error = error;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public String toString() {
            return "PingResult{" + "error=" + error + ", message='" + message + "'" + "}";
        }
    }

    // Inhibit construction
    private WeblogUpdatePinger() {
    }

    /**
     * Send a weblog update ping.
     *
     * @param pingTarget         the target site to ping
     * @param website            the website that changed (from which the ping originates)
     * @return the result message string sent by the server.
     * @throws IOException if an IOException occurs during the ping
     * @throws XmlRpcException if the XML RPC client throws one
     */
    public static PingResult sendPing(PingTarget pingTarget, Weblog website) throws IOException, XmlRpcException {
        String websiteUrl = website.getAbsoluteURL();
        String pingTargetUrl = pingTarget.getPingUrl();
        Set variantOptions = PingConfig.getVariantOptions(pingTargetUrl);

        // Set up the ping parameters.
        List params = new ArrayList();
        if (!variantOptions.contains("noname")) {
            // ping variant for icerocket and anyone with similar bug, where we must omit the blog name.
            params.add(website.getName());
        }
        params.add(websiteUrl);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Executing ping to '" + pingTargetUrl + "' for website '" + websiteUrl + "' (" + website.getName() + ")" + (variantOptions.isEmpty() ? "" : " with variant options " + variantOptions));
        }

        // Send the ping.
        XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
        config.setServerURL(new URL(pingTargetUrl));
        XmlRpcClient client = new XmlRpcClient();
        client.setConfig(config);
        PingResult pingResult = parseResult(client.execute("weblogUpdates.ping", params.toArray()));

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Ping result is: " + pingResult);
        }
        return pingResult;
    }

    private static PingResult parseResult(Object obj) {
        // Deal with the fact that some buggy ping targets may not respond with the proper struct type.
        if (obj == null) {
            return new PingResult(null,null);
        }
        try {
            // normal case: response is a struct (represented as a Map) with Boolean flerror and String fields.
            Map result = (Map) obj;
            return new PingResult((Boolean) result.get("flerror"), (String) result.get("message"));
        } catch (Exception ex) {
            // exception case:  The caller responded with an unexpected type, though parsed at the basic XML RPC level.
            // This effectively assumes flerror = false, and sets message = obj.toString();
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Invalid ping result of type: " + obj.getClass().getName() + "; proceeding with stand-in representative.");
            }
            return new PingResult(null,obj.toString());
        }
    }

    /**
     * Decide if the given exception appears to warrant later retrial attempts.
     *
     * @param ex an exception thrown by the <coce>sendPing</code> operation
     * @return true if the error warrants retrial
     */
    public static boolean shouldRetry(Exception ex) {
        // Determine if error appears transient (warranting retrial)
        // We give most errors the "benefit of the doubt" by considering them transient
        // This picks out a few that we consider non-transient
        if (ex instanceof UnknownHostException) {
            // User probably mistyped the url in the custom target.
            return false;
        } else if (ex instanceof MalformedURLException) {
            // This should never happen due to validations but if we get here, retrial won't fix it.
            return false;
        }
        return true;
    }

}
