/*
 * 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.maven.it;

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

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Collections;

import com.google.common.io.ByteStreams;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.security.UserStore;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.NetworkConnector;
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.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.log.StdErrLog;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.util.security.Password;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;

/**
 * An HTTP server that handles all requests on a given port from a specified source, optionally secured using BASIC auth
 * by providing a username and password. The source can either be a URL or a directory. When a request is made the
 * request is satisfied from the provided source.
 *
 * @author Jason van Zyl
 */
public class HttpServer {
    static {
        Log.initialized();
        Logger rootLogger = Log.getRootLogger();
        if (rootLogger instanceof StdErrLog) {
            ((StdErrLog) rootLogger).setLevel(StdErrLog.LEVEL_WARN);
        }
    }

    private final Server server;

    private final StreamSource source;

    private final String username;

    private final String password;

    public HttpServer(int port, String username, String password, StreamSource source) {
        this.username = username;
        this.password = password;
        this.source = source;
        this.server = server(port);
    }

    public void start() throws Exception {
        server.start();
        // server.join();
    }

    public boolean isFailed() {
        return server.isFailed();
    }

    public void stop() throws Exception {
        server.stop();
    }

    public void join() throws Exception {
        server.join();
    }

    public int port() {
        return ((NetworkConnector) server.getConnectors()[0]).getLocalPort();
    }

    private Server server(int port) {
        QueuedThreadPool threadPool = new QueuedThreadPool();
        threadPool.setMaxThreads(500);
        Server server = new Server(threadPool);
        server.setConnectors(new Connector[] {new ServerConnector(server)});
        server.addBean(new ScheduledExecutorScheduler());

        ServerConnector connector = (ServerConnector) server.getConnectors()[0];
        connector.setIdleTimeout(30_000L);
        connector.setPort(port);

        StreamSourceHandler handler = new StreamSourceHandler(source);

        if (username != null && password != null) {
            HashLoginService loginService = new HashLoginService("Test Server");
            UserStore userStore = new UserStore();
            userStore.addUser(username, new Password(password), new String[] {"user"});
            loginService.setUserStore(userStore);
            server.addBean(loginService);

            ConstraintSecurityHandler security = new ConstraintSecurityHandler();
            server.setHandler(security);

            Constraint constraint = new Constraint();
            constraint.setName("auth");
            constraint.setAuthenticate(true);
            constraint.setRoles(new String[] {"user", "admin"});

            ConstraintMapping mapping = new ConstraintMapping();
            mapping.setPathSpec("/*");
            mapping.setConstraint(constraint);

            security.setConstraintMappings(Collections.singletonList(mapping));
            security.setAuthenticator(new BasicAuthenticator());
            security.setLoginService(loginService);
            security.setHandler(handler);
        } else {
            server.setHandler(handler);
        }
        return server;
    }

    public static HttpServerBuilder builder() {
        return new HttpServerBuilder();
    }

    public static class HttpServerBuilder {

        private int port;

        private String username;

        private String password;

        private StreamSource source;

        public HttpServerBuilder port(int port) {
            this.port = port;
            return this;
        }

        public HttpServerBuilder username(String username) {
            this.username = username;
            return this;
        }

        public HttpServerBuilder password(String password) {
            this.password = password;
            return this;
        }

        public HttpServerBuilder source(final String source) {
            this.source = new StreamSource() {
                @Override
                public InputStream stream(String path) throws IOException {
                    return new URL(String.format("%s/%s", source, path)).openStream();
                }
            };
            return this;
        }

        public HttpServerBuilder source(final File source) {
            this.source = new StreamSource() {
                @Override
                public InputStream stream(String path) throws IOException {
                    return new FileInputStream(new File(source, path));
                }
            };
            return this;
        }

        public HttpServer build() {
            return new HttpServer(port, username, password, source);
        }
    }

    public interface StreamSource {
        InputStream stream(String path) throws IOException;
    }

    public static class StreamSourceHandler extends AbstractHandler {

        private final StreamSource source;

        public StreamSourceHandler(StreamSource source) {
            this.source = source;
        }

        @Override
        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
                throws IOException, ServletException {
            response.setContentType("application/octet-stream");
            response.setStatus(HttpServletResponse.SC_OK);
            try (InputStream in = source.stream(target.substring(1));
                    OutputStream out = response.getOutputStream()) {
                ByteStreams.copy(in, out);
            }
            baseRequest.setHandled(true);
        }
    }

    public static void main(String[] args) throws Exception {
        HttpServer server = HttpServer.builder() //
                .port(0) //
                .username("maven") //
                .password("secret") //
                .source(new File("/tmp/repo")) //
                .build();
        server.start();
    }
}
