package at.reisinger.server.objects;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Verarbeitet einen Request
 * @author Georg Reisinger
 */
public class Request {

    private final PrintStream out;
    private final String       cmd;
    private final String       url;
    private final String payload;
    private final String authString;

    /**
     * Besorgt alle nötigen infos aus dem request
     * @param socket Socket von dem der Request kommt
     * @throws IOException Input Output Exception
     */
    public Request(Socket socket) throws IOException {
        StringBuilder rqBuilder = new StringBuilder();
        this.out = new PrintStream(socket.getOutputStream());
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line = bufferedReader.readLine();
        while (!line.isBlank()) {
            rqBuilder.append(line).append("\r\n");
            line = bufferedReader.readLine();
            System.out.println(line);
        }
        String request = rqBuilder.toString();
        String[] requestsLines = request.split("\r\n");
        String[] requestLine = requestsLines[0].split(" ");
        String method = requestLine[0];
        String path = requestLine[1];
        String version = requestLine[2];
        String host = requestsLines[1].split(" ")[1];

        //code to read the post payload data
        StringBuilder payload = new StringBuilder();
        while(bufferedReader.ready()){
            payload.append((char) bufferedReader.read());
        }
        System.out.println("Payload: " + payload.toString());
        this.payload = payload.toString();

        this.url = path;
        this.cmd = method;

        List<String> headers = new ArrayList<>(Arrays.asList(requestsLines).subList(2, requestsLines.length));



        String accessLog = String.format("Client %s, method %s, path %s, version %s, host %s, headers %s",
                socket.toString(), method, path, version, host, headers.toString());
        System.out.println(accessLog);
        if(headers.toString().contains("Authorization: Basic")) {
            int authIndex = headers.toString().indexOf("Authorization: Basic");
            String authString = headers.toString().substring(authIndex + 21);
            int authIndexEnd = authString.indexOf(',');
            if(authIndexEnd == -1){
                authIndexEnd = authString.indexOf(']');
            }
            authString = authString.substring(0, authIndexEnd);

            this.authString = authString;
        }else{
            this.authString = null;
        }
    }

    /**
     * Auth Header
     * @return get Auth Header
     */
    public String getAuthString() {
        return authString;
    }

    /**
     * Get PrintStream : Output
     *
     * @return out PrintStream : Output
     */
    public PrintStream getOut() {
        return this.out;
    }

    /**
     * Command wie GET, PUT, POST, DEL
     *
     * @return cmd als String
     */
    public String getCmd() {
        return this.cmd;
    }

    /**
     * Request url
     *
     * @return url als String
     */
    public String getUrl() {
        return this.url;
    }

    /**
     * Payload des Request
     *
     * @return payload als String
     */
    public String getPayload() {
        return this.payload;
    }

}
