/*
 *  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.tools.ant.taskdefs.condition;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectComponent;

/**
 * <p>Test for a host being reachable using ICMP "ping" packets &amp; echo operations.
 * Ping packets are very reliable for assessing reachability in a LAN or WAN,
 * but they do not get through any well-configured firewall. Echo (port 7) may.</p>
 *
 * <p>This condition turns unknown host exceptions into false conditions. This is
 * because on a laptop, DNS is one of the first services lost when the network
 * goes; you are implicitly offline.</p>
 *
 * <p>If a URL is supplied instead of a host, the hostname is extracted and used in
 * the test--all other parts of the URL are discarded.</p>
 *
 * <p>The test may not work through firewalls; that is, something may be reachable
 * using a protocol such as HTTP, while the lower level ICMP packets get dropped
 * on the floor. Similarly, a host may be detected as reachable with ICMP, but not
 * reachable on other ports (i.e. port 80), because of firewalls.</p>
 *
 * @since Ant 1.7
 */
public class IsReachable extends ProjectComponent implements Condition {

    private static final int SECOND = 1000; // millis per second
    private String host;
    private String url;

    /**
     * The default timeout.
     */
    public static final int DEFAULT_TIMEOUT = 30;
    private int timeout = DEFAULT_TIMEOUT;
    /**
     * Error when no hostname is defined
     */
    public static final String ERROR_NO_HOSTNAME = "No hostname defined";
    /**
     * Error when invalid timeout value is defined
     */
    public static final String ERROR_BAD_TIMEOUT = "Invalid timeout value";
    /**
     * Unknown host message is seen.
     */
    private static final String WARN_UNKNOWN_HOST = "Unknown host: ";
    /**
     * Network error message is seen.
     */
    public static final String ERROR_ON_NETWORK = "network error to ";
    /** Error message when url and host are specified. */
    public static final String ERROR_BOTH_TARGETS
        = "Both url and host have been specified";
    /** Error message when no reachably test avail. */
    public static final String MSG_NO_REACHABLE_TEST
        = "cannot do a proper reachability test on this Java version";
    /** Error message when an invalid url is used. */
    public static final String ERROR_BAD_URL = "Bad URL ";
    /** Error message when no hostname in url. */
    public static final String ERROR_NO_HOST_IN_URL = "No hostname in URL ";
    /**
     * The method name to look for in InetAddress
     * @deprecated Since 1.9.14
     */
    @Deprecated
    public static final String METHOD_NAME = "isReachable";

    /**
     * Set the host to ping.
     *
     * @param host the host to ping.
     */
    public void setHost(final String host) {
        this.host = host;
    }

    /**
     * Set the URL from which to extract the hostname.
     *
     * @param url a URL object.
     */
    public void setUrl(final String url) {
        this.url = url;
    }

    /**
     * Set the timeout for the reachability test in seconds.
     *
     * @param timeout the timeout in seconds.
     */
    public void setTimeout(final int timeout) {
        this.timeout = timeout;
    }

    /**
     * emptyness test
     *
     * @param string param to check
     *
     * @return true if it is empty
     */
    private boolean empty(final String string) {
        return string == null || string.length() == 0;
    }

    /**
     * Evaluate the condition.
     *
     * @return true if the condition is true.
     *
     * @throws BuildException
     *          if an error occurs
     */
    public boolean eval() throws BuildException {
        if (empty(host) && empty(url)) {
            throw new BuildException(ERROR_NO_HOSTNAME);
        }
        if (timeout < 0) {
            throw new BuildException(ERROR_BAD_TIMEOUT);
        }
        String target = host;
        if (!empty(url)) {
            if (!empty(host)) {
                throw new BuildException(ERROR_BOTH_TARGETS);
            }
            try {
                //get the host of a url
                final URL realURL = new URL(url);
                target = realURL.getHost();
                if (empty(target)) {
                    throw new BuildException(ERROR_NO_HOST_IN_URL + url);
                }
            } catch (final MalformedURLException e) {
                throw new BuildException(ERROR_BAD_URL + url, e);
            }
        }
        log("Probing host " + target, Project.MSG_VERBOSE);
        InetAddress address;
        try {
            address = InetAddress.getByName(target);
        } catch (final UnknownHostException e1) {
            log(WARN_UNKNOWN_HOST + target);
            return false;
        }
        log("Host address = " + address.getHostAddress(),
                Project.MSG_VERBOSE);
        boolean reachable;
        try {
            reachable = address.isReachable(timeout * SECOND);
        } catch (final IOException ioe) {
            reachable = false;
            log(ERROR_ON_NETWORK + target + ": " + ioe.toString());
        }

        log("host is" + (reachable ? "" : " not") + " reachable", Project.MSG_VERBOSE);
        return reachable;
    }
}
