package org.eclipse.aether.transport.http;

/*
 * 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.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.aether.util.ChecksumUtils;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.util.B64Code;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpServer
{

    public static class LogEntry
    {

        public final String method;

        public final String path;

        public final Map<String, String> headers;

        public LogEntry( String method, String path, Map<String, String> headers )
        {
            this.method = method;
            this.path = path;
            this.headers = headers;
        }

        @Override
        public String toString()
        {
            return method + " " + path;
        }

    }

    public enum ExpectContinue
    {
        FAIL, PROPER, BROKEN
    }

    public enum ChecksumHeader
    {
        NEXUS
    }

    private static final Logger LOGGER = LoggerFactory.getLogger( HttpServer.class );

    private File repoDir;

    private boolean rangeSupport = true;

    private boolean webDav;

    private ExpectContinue expectContinue = ExpectContinue.PROPER;

    private ChecksumHeader checksumHeader;

    private Server server;

    private ServerConnector httpConnector;

    private ServerConnector httpsConnector;

    private String username;

    private String password;

    private String proxyUsername;

    private String proxyPassword;

    private List<LogEntry> logEntries = Collections.synchronizedList( new ArrayList<LogEntry>() );

    public String getHost()
    {
        return "localhost";
    }

    public int getHttpPort()
    {
        return httpConnector != null ? httpConnector.getLocalPort() : -1;
    }

    public int getHttpsPort()
    {
        return httpsConnector != null ? httpsConnector.getLocalPort() : -1;
    }

    public String getHttpUrl()
    {
        return "http://" + getHost() + ":" + getHttpPort();
    }

    public String getHttpsUrl()
    {
        return "https://" + getHost() + ":" + getHttpsPort();
    }

    public HttpServer addSslConnector()
    {
        if ( httpsConnector == null )
        {
            SslContextFactory ssl = new SslContextFactory();
            ssl.setKeyStorePath( new File( "src/test/resources/ssl/server-store" ).getAbsolutePath() );
            ssl.setKeyStorePassword( "server-pwd" );
            ssl.setTrustStorePath( new File( "src/test/resources/ssl/client-store" ).getAbsolutePath() );
            ssl.setTrustStorePassword( "client-pwd" );
            ssl.setNeedClientAuth( true );
            httpsConnector = new ServerConnector( server, ssl );
            server.addConnector( httpsConnector );
            try
            {
                httpsConnector.start();
            }
            catch ( Exception e )
            {
                throw new IllegalStateException( e );
            }
        }
        return this;
    }

    public List<LogEntry> getLogEntries()
    {
        return logEntries;
    }

    public HttpServer setRepoDir( File repoDir )
    {
        this.repoDir = repoDir;
        return this;
    }

    public HttpServer setRangeSupport( boolean rangeSupport )
    {
        this.rangeSupport = rangeSupport;
        return this;
    }

    public HttpServer setWebDav( boolean webDav )
    {
        this.webDav = webDav;
        return this;
    }

    public HttpServer setExpectSupport( ExpectContinue expectContinue )
    {
        this.expectContinue = expectContinue;
        return this;
    }

    public HttpServer setChecksumHeader( ChecksumHeader checksumHeader )
    {
        this.checksumHeader = checksumHeader;
        return this;
    }

    public HttpServer setAuthentication( String username, String password )
    {
        this.username = username;
        this.password = password;
        return this;
    }

    public HttpServer setProxyAuthentication( String username, String password )
    {
        proxyUsername = username;
        proxyPassword = password;
        return this;
    }

    public HttpServer start()
        throws Exception
    {
        if ( server != null )
        {
            return this;
        }

        HandlerList handlers = new HandlerList();
        handlers.addHandler( new LogHandler() );
        handlers.addHandler( new ProxyAuthHandler() );
        handlers.addHandler( new AuthHandler() );
        handlers.addHandler( new RedirectHandler() );
        handlers.addHandler( new RepoHandler() );

        server = new Server();
        httpConnector = new ServerConnector( server );
        server.addConnector( httpConnector );
        server.setHandler( handlers );
        server.start();

        return this;
    }

    public void stop()
        throws Exception
    {
        if ( server != null )
        {
            server.stop();
            server = null;
            httpConnector = null;
            httpsConnector = null;
        }
    }

    private class LogHandler
        extends AbstractHandler
    {

        @SuppressWarnings( "unchecked" )
        public void handle( String target, Request req, HttpServletRequest request, HttpServletResponse response )
            throws IOException
        {
            LOGGER.info( "{} {}{}", req.getMethod(), req.getRequestURL(),
                    req.getQueryString() != null ? "?" + req.getQueryString() : "");

            Map<String, String> headers = new TreeMap<String, String>( String.CASE_INSENSITIVE_ORDER );
            for ( Enumeration<String> en = req.getHeaderNames(); en.hasMoreElements(); )
            {
                String name = en.nextElement();
                StringBuilder buffer = new StringBuilder( 128 );
                for ( Enumeration<String> ien = req.getHeaders( name ); ien.hasMoreElements(); )
                {
                    if ( buffer.length() > 0 )
                    {
                        buffer.append( ", " );
                    }
                    buffer.append( ien.nextElement() );
                }
                headers.put( name, buffer.toString() );
            }
            logEntries.add( new LogEntry( req.getMethod(), req.getPathInfo(), Collections.unmodifiableMap( headers ) ) );
        }

    }

    private class RepoHandler
        extends AbstractHandler
    {

        private final Pattern SIMPLE_RANGE = Pattern.compile( "bytes=([0-9])+-" );

        public void handle( String target, Request req, HttpServletRequest request, HttpServletResponse response )
            throws IOException
        {
            String path = req.getPathInfo().substring( 1 );

            if ( !path.startsWith( "repo/" ) )
            {
                return;
            }
            req.setHandled( true );

            if ( ExpectContinue.FAIL.equals( expectContinue ) && request.getHeader( HttpHeader.EXPECT.asString() ) != null )
            {
                response.setStatus( HttpServletResponse.SC_EXPECTATION_FAILED );
                return;
            }

            File file = new File( repoDir, path.substring( 5 ) );
            if ( HttpMethod.GET.is( req.getMethod() ) || HttpMethod.HEAD.is( req.getMethod() ) )
            {
                if ( !file.isFile() || path.endsWith( URIUtil.SLASH ) )
                {
                    response.setStatus( HttpServletResponse.SC_NOT_FOUND );
                    return;
                }
                long ifUnmodifiedSince = request.getDateHeader( HttpHeader.IF_UNMODIFIED_SINCE.asString() );
                if ( ifUnmodifiedSince != -1L && file.lastModified() > ifUnmodifiedSince )
                {
                    response.setStatus( HttpServletResponse.SC_PRECONDITION_FAILED );
                    return;
                }
                long offset = 0L;
                String range = request.getHeader( HttpHeader.RANGE.asString() );
                if ( range != null && rangeSupport )
                {
                    Matcher m = SIMPLE_RANGE.matcher( range );
                    if ( m.matches() )
                    {
                        offset = Long.parseLong( m.group( 1 ) );
                        if ( offset >= file.length() )
                        {
                            response.setStatus( HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE );
                            return;
                        }
                    }
                    String encoding = request.getHeader( HttpHeader.ACCEPT_ENCODING.asString() );
                    if ( ( encoding != null && !"identity".equals( encoding ) ) || ifUnmodifiedSince == -1L )
                    {
                        response.setStatus( HttpServletResponse.SC_BAD_REQUEST );
                        return;
                    }
                }
                response.setStatus( ( offset > 0L ) ? HttpServletResponse.SC_PARTIAL_CONTENT : HttpServletResponse.SC_OK );
                response.setDateHeader( HttpHeader.LAST_MODIFIED.asString(), file.lastModified() );
                response.setHeader( HttpHeader.CONTENT_LENGTH.asString(), Long.toString( file.length() - offset ) );
                if ( offset > 0L )
                {
                    response.setHeader( HttpHeader.CONTENT_RANGE.asString(), "bytes " + offset + "-" + ( file.length() - 1L )
                        + "/" + file.length() );
                }
                if ( checksumHeader != null )
                {
                    Map<String, Object> checksums = ChecksumUtils.calc( file, Collections.singleton( "SHA-1" ) );
                    switch ( checksumHeader )
                    {
                        case NEXUS:
                            response.setHeader( HttpHeader.ETAG.asString(), "{SHA1{" + checksums.get( "SHA-1" ) + "}}" );
                            break;
                    }
                }
                if ( HttpMethod.HEAD.is( req.getMethod() ) )
                {
                    return;
                }
                FileInputStream is = null;
                try
                {
                    is = new FileInputStream( file );
                    if ( offset > 0L )
                    {
                        long skipped = is.skip( offset );
                        while ( skipped < offset && is.read() >= 0 )
                        {
                            skipped++;
                        }
                    }
                    IO.copy( is, response.getOutputStream() );
                    is.close();
                    is = null;
                }
                finally
                {
                    try
                    {
                        if ( is != null )
                        {
                            is.close();
                        }
                    }
                    catch ( final IOException e )
                    {
                        // Suppressed due to an exception already thrown in the try block.
                    }
                }
            }
            else if ( HttpMethod.PUT.is( req.getMethod() ) )
            {
                if ( !webDav )
                {
                    file.getParentFile().mkdirs();
                }
                if ( file.getParentFile().exists() )
                {
                    try
                    {
                        FileOutputStream os = null;
                        try
                        {
                            os = new FileOutputStream( file );
                            IO.copy( request.getInputStream(), os );
                            os.close();
                            os = null;
                        }
                        finally
                        {
                            try
                            {
                                if ( os != null )
                                {
                                    os.close();
                                }
                            }
                            catch ( final IOException e )
                            {
                                // Suppressed due to an exception already thrown in the try block.
                            }
                        }
                    }
                    catch ( IOException e )
                    {
                        file.delete();
                        throw e;
                    }
                    response.setStatus( HttpServletResponse.SC_NO_CONTENT );
                }
                else
                {
                    response.setStatus( HttpServletResponse.SC_FORBIDDEN );
                }
            }
            else if ( HttpMethod.OPTIONS.is( req.getMethod() ) )
            {
                if ( webDav )
                {
                    response.setHeader( "DAV", "1,2" );
                }
                response.setHeader( HttpHeader.ALLOW.asString(), "GET, PUT, HEAD, OPTIONS" );
                response.setStatus( HttpServletResponse.SC_OK );
            }
            else if ( webDav && "MKCOL".equals( req.getMethod() ) )
            {
                if ( file.exists() )
                {
                    response.setStatus( HttpServletResponse.SC_METHOD_NOT_ALLOWED );
                }
                else if ( file.mkdir() )
                {
                    response.setStatus( HttpServletResponse.SC_CREATED );
                }
                else
                {
                    response.setStatus( HttpServletResponse.SC_CONFLICT );
                }
            }
            else
            {
                response.setStatus( HttpServletResponse.SC_METHOD_NOT_ALLOWED );
            }
        }

    }

    private class RedirectHandler
        extends AbstractHandler
    {

        public void handle( String target, Request req, HttpServletRequest request, HttpServletResponse response )
            throws IOException
        {
            String path = req.getPathInfo();
            if ( !path.startsWith( "/redirect/" ) )
            {
                return;
            }
            req.setHandled( true );
            StringBuilder location = new StringBuilder( 128 );
            String scheme = req.getParameter( "scheme" );
            location.append( scheme != null ? scheme : req.getScheme() );
            location.append( "://" );
            location.append( req.getServerName() );
            location.append( ":" );
            if ( "http".equalsIgnoreCase( scheme ) )
            {
                location.append( getHttpPort() );
            }
            else if ( "https".equalsIgnoreCase( scheme ) )
            {
                location.append( getHttpsPort() );
            }
            else
            {
                location.append( req.getServerPort() );
            }
            location.append( "/repo" ).append( path.substring( 9 ) );
            response.setStatus( HttpServletResponse.SC_MOVED_PERMANENTLY );
            response.setHeader( HttpHeader.LOCATION.asString(), location.toString() );
        }

    }

    private class AuthHandler
        extends AbstractHandler
    {

        public void handle( String target, Request req, HttpServletRequest request, HttpServletResponse response )
            throws IOException
        {
            if ( ExpectContinue.BROKEN.equals( expectContinue )
                && "100-continue".equalsIgnoreCase( request.getHeader( HttpHeader.EXPECT.asString() ) ) )
            {
                request.getInputStream();
            }

            if ( username != null && password != null )
            {
                if ( checkBasicAuth( request.getHeader( HttpHeader.AUTHORIZATION.asString() ), username, password ) )
                {
                    return;
                }
                req.setHandled( true );
                response.setHeader( HttpHeader.WWW_AUTHENTICATE.asString(), "basic realm=\"Test-Realm\"" );
                response.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
            }
        }

    }

    private class ProxyAuthHandler
        extends AbstractHandler
    {

        public void handle( String target, Request req, HttpServletRequest request, HttpServletResponse response )
            throws IOException
        {
            if ( proxyUsername != null && proxyPassword != null )
            {
                if ( checkBasicAuth( request.getHeader( HttpHeader.PROXY_AUTHORIZATION.asString() ), proxyUsername, proxyPassword ) )
                {
                    return;
                }
                req.setHandled( true );
                response.setHeader( HttpHeader.PROXY_AUTHENTICATE.asString(), "basic realm=\"Test-Realm\"" );
                response.setStatus( HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED );
            }
        }

    }

    static boolean checkBasicAuth( String credentials, String username, String password )
    {
        if ( credentials != null )
        {
            int space = credentials.indexOf( ' ' );
            if ( space > 0 )
            {
                String method = credentials.substring( 0, space );
                if ( "basic".equalsIgnoreCase( method ) )
                {
                    credentials = credentials.substring( space + 1 );
                    credentials = B64Code.decode( credentials, StringUtil.__ISO_8859_1 );
                    int i = credentials.indexOf( ':' );
                    if ( i > 0 )
                    {
                        String user = credentials.substring( 0, i );
                        String pass = credentials.substring( i + 1 );
                        if ( username.equals( user ) && password.equals( pass ) )
                        {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

}
