package org.apache.maven.plugins.javadoc;

/*
 * 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.
 */

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.security.B64Code;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.proxy.AsyncProxyServlet;

/**
 * A Proxy server.
 *
 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
 * @version $Id: ProxyServer.java 1517906 2013-08-27 18:25:03Z krosenvold $
 * @since 2.6
 */
class ProxyServer
{
    private Server proxyServer;

    /**
     * @param proxyServlet the wanted auth proxy servlet
     */
    public ProxyServer( AuthAsyncProxyServlet proxyServlet )
    {
        this( null, 0, proxyServlet );
    }

    /**
     * @param hostName the server name
     * @param port the server port
     * @param debug true to display System.err, false otherwise.
     * @param proxyServlet the wanted auth proxy servlet
     */
    public ProxyServer( String hostName, int port, AuthAsyncProxyServlet proxyServlet )
    {
        proxyServer = new Server();

        proxyServer.addConnector( getDefaultConnector( hostName, port ) );

        Context context = new Context( proxyServer, "/", 0 );

        context.addServlet( new ServletHolder( proxyServlet ), "/" );
    }

    /**
     * @return the host name
     */
    public String getHostName()
    {
        Connector connector = proxyServer.getConnectors()[0];
        return connector.getHost();
    }

    /**
     * @return the host port
     */
    public int getPort()
    {
        Connector connector = proxyServer.getConnectors()[0];
        return ( connector.getLocalPort() <= 0 ? connector.getPort() : connector.getLocalPort() );
    }

    /**
     * @throws Exception if any
     */
    public void start()
        throws Exception
    {
        if ( proxyServer != null )
        {
            proxyServer.start();
        }
    }

    /**
     * @throws Exception if any
     */
    public void stop()
        throws Exception
    {
        if ( proxyServer != null )
        {
            proxyServer.stop();
        }
        proxyServer = null;
    }

    private Connector getDefaultConnector( String hostName, int port )
    {
        Connector connector = new SocketConnector();
        if ( hostName != null )
        {
            connector.setHost( hostName );
        }
        else
        {
            try
            {
                connector.setHost( InetAddress.getLocalHost().getCanonicalHostName() );
            }
            catch ( UnknownHostException e )
            {
                // nop
            }
        }
        if ( port > 0 )
        {
            connector.setPort( port );
        }

        return connector;
    }

    /**
     * A proxy servlet with authentication support.
     */
    static class AuthAsyncProxyServlet
        extends AsyncProxyServlet
    {
        private Map<String, String> authentications;

        private long sleepTime = 0;

        /**
         * Constructor for non authentication servlet.
         */
        public AuthAsyncProxyServlet()
        {
            super();
        }

        /**
         * Constructor for authentication servlet.
         *
         * @param authentications a map of user/password
         */
        public AuthAsyncProxyServlet( Map<String, String> authentications )
        {
            this();

            this.authentications = authentications;
        }

        /**
         * Constructor for authentication servlet.
         *
         * @param authentications a map of user/password
         * @param sleepTime a positive time to sleep the service thread (for timeout)
         */
        public AuthAsyncProxyServlet( Map<String, String> authentications, long sleepTime )
        {
            this();

            this.authentications = authentications;
            this.sleepTime = sleepTime;
        }

        /** {@inheritDoc} */
        @Override
        public void service( ServletRequest req, ServletResponse res )
            throws ServletException, IOException
        {
            final HttpServletRequest request = (HttpServletRequest) req;
            final HttpServletResponse response = (HttpServletResponse) res;

            if ( this.authentications != null && !this.authentications.isEmpty() )
            {
                String proxyAuthorization = request.getHeader( "Proxy-Authorization" );
                if ( proxyAuthorization != null && proxyAuthorization.startsWith( "Basic " ) )
                {
                    String proxyAuth = proxyAuthorization.substring( 6 );
                    String authorization = B64Code.decode( proxyAuth );
                    String[] authTokens = authorization.split( ":" );
                    String user = authTokens[0];
                    String password = authTokens[1];

                    if ( this.authentications.get( user ) == null )
                    {
                        throw new IllegalArgumentException( user + " not found in the map!" );
                    }

                    if ( sleepTime > 0 )
                    {
                        try
                        {
                            Thread.sleep( sleepTime );
                        }
                        catch ( InterruptedException e )
                        {
                            // nop
                        }
                    }
                    String authPass = this.authentications.get(user);
                    if ( password.equals( authPass ) )
                    {
                        // could throw exceptions...
                        super.service( req, res );
                        return;
                    }
                }

                // Proxy-Authenticate Basic realm="CCProxy Authorization"
                response.addHeader( "Proxy-Authenticate", "Basic realm=\"Jetty Proxy Authorization\"" );
                response.setStatus( HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED );
                return;
            }

            super.service( req, res );
        }
    }
}