/*
 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */


import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.nio.file.Files;
import java.util.Date;

/*
 * This is simple HTTP server implementation that is based on com.sun.net.httpserver API.
 * The server returns requested files from base directory.
 * If a file does not exist it returns 404.
 * Directory browsing is not supported (403 error is returned in this case).
 *
 */
public class SimpleHttpServer extends AbstractHttpSockServer {

    private String basedir;

    public SimpleHttpServer(int port, String basedir) {
        super(port);
        this.basedir = basedir;
    }

    @Override
    protected Runnable createClientConnectionHandler(final Socket socket) {
        return new Runnable() {

            @Override
            public void run() {
                try {
                    InputStream is = socket.getInputStream();
                    String requestLine = Utils.readLine(is);
                    System.out.println("SHIVANGI  requestLine  " + requestLine);
                    String[] requestLineParts = requestLine.split(" ");
                    System.out.println("SHIVANGI requestLineParts[1]" + requestLineParts[1]);
                    if (requestLineParts.length < 2) {
                        throw new Exception("Got wrong HTTP request with request line: " + requestLine);
                    }
                    if (!"GET".equalsIgnoreCase(requestLineParts[0])) {
                        throw new Exception("Only GET method is supported");
                    }

                    String path = basedir + System.getProperty("file.separator") + requestLineParts[1];
                    File file = new File(path);
                    BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());

                    if (!file.exists()) {
                        System.out.println("Httpserver: requested path '" + path + "' does not exist -> 404 error");
                        bos.write("HTTP/1.0 404 Not found\n".getBytes());
                    } else if (file.isDirectory()) {
                        System.out.println("Httpserver: requested path '" + path + "' is directory -> 403 error");
                        bos.write("HTTP/1.0 403 Forbidden\n".getBytes());
                    } else {
                        System.out
                        .println("Httpserver: requested path '" + path + "' is file -> return requested file");
                        byte[] content = Files.readAllBytes(file.toPath());

                        StringBuilder sb = new StringBuilder();
                        sb.append("HTTP/1.0 200 OK\n");
                        sb.append("Content-Length: ");
                        sb.append(String.valueOf(content.length));
                        sb.append("Last-Modified: ");
                        sb.append(new Date(System.currentTimeMillis()).toString());
                        sb.append("\n\n");

                        bos.write(sb.toString().getBytes());
                        bos.write(content);
                    }

                    bos.flush();
                    bos.close();
                } catch (Exception e) {
                    System.out.println("Got Exception" + e);
                } finally {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        System.out.println("Got Exception" + e);
                    }
                }
            }
        };
    }

    @Override
    protected void printStartMessage() {
        System.out.println("Simple HTTP server has been started on {0} port" + getPort());
    }
}
