/*
 *  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.optional.net;

import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.util.Properties;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.util.ProxySetup;

/**
 * Sets Java's web proxy properties, so that tasks and code run in
 * the same JVM can have through-the-firewall access to remote web sites,
 * and remote ftp sites.
 * You can nominate an http and ftp proxy, or a socks server, reset the server
 * settings, or do nothing at all.
 * <p>
 * Examples
 * <pre>&lt;setproxy/&gt;</pre>
 * do nothing
 * <pre>&lt;setproxy proxyhost="firewall"/&gt;</pre>
 * set the proxy to firewall:80
 * <pre>&lt;setproxy proxyhost="firewall" proxyport="81"/&gt;</pre>
 * set the proxy to firewall:81
 * <pre>&lt;setproxy proxyhost=""/&gt;</pre>
 * stop using the http proxy; don't change the socks settings
 * <pre>&lt;setproxy socksproxyhost="socksy"/&gt;</pre>
 * use socks via socksy:1080
 * <pre>&lt;setproxy socksproxyhost=""/&gt;</pre>
 * stop using the socks server.
 * <p>
 * You can set a username and password for http with the <tt>proxyHost</tt>
 * and <tt>proxyPassword</tt> attributes. These can also be
 * used against SOCKS5 servers.
 * </p>
 * @see <a href="http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html">
 *  java 1.5 network property list</a>
  *@since       Ant 1.5
 * @ant.task category="network"
 */
public class SetProxy extends Task {
    private static final int HTTP_PORT = 80;
    private static final int SOCKS_PORT = 1080;
    // CheckStyle:VisibilityModifier OFF - bc
    /**
     * proxy details
     */
    protected String proxyHost = null;

    /**
     * name of proxy port
     */
    protected int proxyPort = HTTP_PORT;

    // CheckStyle:VisibilityModifier ON

    /**
     * socks host.
     */
    private String socksProxyHost = null;

    /**
     * Socks proxy port. Default is 1080.
     */
    private int socksProxyPort = SOCKS_PORT;


    /**
     * list of non proxy hosts
     */
    private String nonProxyHosts = null;

    /**
     * user for http only
     */
    private String proxyUser = null;

    /**
     * password for http only
     */
    private String proxyPassword = null;

    /**
     * the HTTP/ftp proxy host. Set this to "" for the http proxy
     * option to be disabled
     *
     * @param hostname the new proxy hostname
     */
    public void setProxyHost(String hostname) {
        proxyHost = hostname;
    }


    /**
     * the HTTP/ftp proxy port number; default is 80
     *
     * @param port port number of the proxy
     */
    public void setProxyPort(int port) {
        proxyPort = port;
    }

    /**
     * The name of a Socks server. Set to "" to turn socks
     * proxying off.
     *
     * @param host The new SocksProxyHost value
     */
    public void setSocksProxyHost(String host) {
        this.socksProxyHost = host;
    }


    /**
     * Set the ProxyPort for socks connections. The default value is 1080
     *
     * @param port The new SocksProxyPort value
     */
    public void setSocksProxyPort(int port) {
        this.socksProxyPort = port;
    }


    /**
     * A list of hosts to bypass the proxy on. These should be separated
     * with the vertical bar character '|'. Only in Java 1.4 does ftp use
     * this list.
     * e.g. fozbot.corp.sun.com|*.eng.sun.com
     * @param nonProxyHosts lists of hosts to talk direct to
     */
    public void setNonProxyHosts(String nonProxyHosts) {
        this.nonProxyHosts = nonProxyHosts;
    }

    /**
     * set the proxy user. Probably requires a password to accompany this
     * setting. Default=""
     * @param proxyUser username
     * @since Ant1.6
     */
    public void setProxyUser(String proxyUser) {
        this.proxyUser = proxyUser;
    }

    /**
     * Set the password for the proxy. Used only if the proxyUser is set.
     * @param proxyPassword password to go with the username
     * @since Ant1.6
     */
    public void setProxyPassword(String proxyPassword) {
        this.proxyPassword = proxyPassword;
    }

    /**
     * if the proxy port and host settings are not null, then the settings
     * get applied these settings last beyond the life of the object and
     * apply to all network connections
     * Relevant docs: buglist #4183340
     */

    public void applyWebProxySettings() {
        boolean settingsChanged = false;
        boolean enablingProxy = false;
        Properties sysprops = System.getProperties();
        if (proxyHost != null) {
            settingsChanged = true;
            if (proxyHost.length() != 0) {
                traceSettingInfo();
                enablingProxy = true;
                sysprops.put(ProxySetup.HTTP_PROXY_HOST, proxyHost);
                String portString = Integer.toString(proxyPort);
                sysprops.put(ProxySetup.HTTP_PROXY_PORT, portString);
                sysprops.put(ProxySetup.HTTPS_PROXY_HOST, proxyHost);
                sysprops.put(ProxySetup.HTTPS_PROXY_PORT, portString);
                sysprops.put(ProxySetup.FTP_PROXY_HOST, proxyHost);
                sysprops.put(ProxySetup.FTP_PROXY_PORT, portString);
                if (nonProxyHosts != null) {
                    sysprops.put(ProxySetup.HTTP_NON_PROXY_HOSTS, nonProxyHosts);
                    sysprops.put(ProxySetup.HTTPS_NON_PROXY_HOSTS, nonProxyHosts);
                    sysprops.put(ProxySetup.FTP_NON_PROXY_HOSTS, nonProxyHosts);
                }
                if (proxyUser != null) {
                    sysprops.put(ProxySetup.HTTP_PROXY_USERNAME, proxyUser);
                    sysprops.put(ProxySetup.HTTP_PROXY_PASSWORD, proxyPassword);
                }
            } else {
                log("resetting http proxy", Project.MSG_VERBOSE);
                sysprops.remove(ProxySetup.HTTP_PROXY_HOST);
                sysprops.remove(ProxySetup.HTTP_PROXY_PORT);
                sysprops.remove(ProxySetup.HTTP_PROXY_USERNAME);
                sysprops.remove(ProxySetup.HTTP_PROXY_PASSWORD);
                sysprops.remove(ProxySetup.HTTPS_PROXY_HOST);
                sysprops.remove(ProxySetup.HTTPS_PROXY_PORT);
                sysprops.remove(ProxySetup.FTP_PROXY_HOST);
                sysprops.remove(ProxySetup.FTP_PROXY_PORT);
            }
        }

        //socks
        if (socksProxyHost != null) {
            settingsChanged = true;
            if (socksProxyHost.length() != 0) {
                enablingProxy = true;
                sysprops.put(ProxySetup.SOCKS_PROXY_HOST, socksProxyHost);
                sysprops.put(ProxySetup.SOCKS_PROXY_PORT, Integer.toString(socksProxyPort));
                if (proxyUser != null) {
                    //this may be a java1.4 thingy only
                    sysprops.put(ProxySetup.SOCKS_PROXY_USERNAME, proxyUser);
                    sysprops.put(ProxySetup.SOCKS_PROXY_PASSWORD, proxyPassword);
                }

            } else {
                log("resetting socks proxy", Project.MSG_VERBOSE);
                sysprops.remove(ProxySetup.SOCKS_PROXY_HOST);
                sysprops.remove(ProxySetup.SOCKS_PROXY_PORT);
                sysprops.remove(ProxySetup.SOCKS_PROXY_USERNAME);
                sysprops.remove(ProxySetup.SOCKS_PROXY_PASSWORD);
            }
        }

        if (proxyUser != null) {
            if (enablingProxy) {
                Authenticator.setDefault(new ProxyAuth(proxyUser,
                                                       proxyPassword));
            } else if (settingsChanged) {
                Authenticator.setDefault(new ProxyAuth("", ""));
            }
        }
    }

    /**
     * list out what is going on
     */
    private void traceSettingInfo() {
        log("Setting proxy to "
                + (proxyHost != null ? proxyHost : "''")
                + ":" + proxyPort,
                Project.MSG_VERBOSE);
    }

    /**
     * Does the work.
     *
     * @exception BuildException thrown in unrecoverable error.
     */
    public void execute() throws BuildException {
        applyWebProxySettings();
    }

    /**
     * @since 1.6.3
     */
    private static final class ProxyAuth extends Authenticator {
        private PasswordAuthentication auth;

        private ProxyAuth(String user, String pass) {
            auth = new PasswordAuthentication(user, pass.toCharArray());
        }

        protected PasswordAuthentication getPasswordAuthentication() {
            return auth;
        }
    }
}

