/*
 *  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.coyote.ajp;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.Locale;

import javax.net.SocketFactory;

/**
 * AJP client that is not (yet) a full AJP client implementation as it just
 * provides the functionality required for the unit tests. The client uses
 * blocking IO throughout.
 */
public class SimpleAjpClient {

    private static final int DEFAULT_AJP_PACKET_SIZE = 8192;
    private static final byte[] AJP_CPING;

    static {
        TesterAjpMessage ajpCping = new TesterAjpMessage(16);
        ajpCping.reset();
        ajpCping.appendByte(Constants.JK_AJP13_CPING_REQUEST);
        ajpCping.end();
        AJP_CPING = new byte[ajpCping.getLen()];
        System.arraycopy(ajpCping.getBuffer(), 0, AJP_CPING, 0,
                ajpCping.getLen());
    }

    private final int packetSize;
    private String host = "localhost";
    private int port = -1;
    /* GET == 2 */
    private int method = 2;
    private String protocol = "http";
    private String uri = "/";
    private String remoteAddr = "192.168.0.1";
    private String remoteHost = "client.example.com";
    private String serverName = "www.example.com";
    private int serverPort = 80;
    private boolean ssl = false;
    private Socket socket = null;

    public SimpleAjpClient() {
        this(DEFAULT_AJP_PACKET_SIZE);
    }

    public SimpleAjpClient(int packetSize) {
        this.packetSize = packetSize;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public int getPort() {
        return port;
    }

    public void setMethod(String method) {
        method = method.toUpperCase(Locale.ENGLISH);
        switch (method) {
            case "OPTIONS":
                this.method = 1;
                break;
            case "GET":
                this.method = 2;
                break;
            case "HEAD":
                this.method = 3;
                break;
            case "POST":
                this.method = 4;
                break;
            case "PUT":
                this.method = 5;
                break;
            case "DELETE":
                this.method = 6;
                break;
            case "TRACE":
                this.method = 7;
                break;
            case "PROPFIND":
                this.method = 8;
                break;
            case "PROPPATCH":
                this.method = 9;
                break;
            case "MKCOL":
                this.method = 10;
                break;
            case "COPY":
                this.method = 11;
                break;
            case "MOVE":
                this.method = 12;
                break;
            case "LOCK":
                this.method = 13;
                break;
            case "UNLOCK":
                this.method = 14;
                break;
            case "ACL":
                this.method = 15;
                break;
            case "REPORT":
                this.method = 16;
                break;
            case "VERSION-CONTROL":
                this.method = 17;
                break;
            case "CHECKIN":
                this.method = 18;
                break;
            case "CHECKOUT":
                this.method = 19;
                break;
            case "UNCHECKOUT":
                this.method = 20;
                break;
            case "SEARCH":
                this.method = 21;
                break;
            case "MKWORKSPACE":
                this.method = 22;
                break;
            case "UPDATE":
                this.method = 23;
                break;
            case "LABEL":
                this.method = 24;
                break;
            case "MERGE":
                this.method = 25;
                break;
            case "BASELINE-CONTROL":
                this.method = 26;
                break;
            case "MKACTIVITY":
                this.method = 27;
                break;
            default:
                this.method = 99;
        }
    }

    public String getMethod() {
        switch (method) {
            case 1:
                return "OPTIONS";
            case 2:
                return "GET";
            case 3:
                return "HEAD";
            case 4:
                return "POST";
            case 5:
                return "PUT";
            case 6:
                return "DELETE";
            case 7:
                return "TRACE";
            case 8:
                return "PROPFIND";
            case 9:
                return "PROPPATCH";
            case 10:
                return "MKCOL";
            case 11:
                return "COPY";
            case 12:
                return "MOVE";
            case 13:
                return "LOCK";
            case 14:
                return "UNLOCK";
            case 15:
                return "ACL";
            case 16:
                return "REPORT";
            case 17:
                return "VERSION-CONTROL";
            case 18:
                return "CHECKIN";
            case 19:
                return "CHECKOUT";
            case 20:
                return "UNCHECKOUT";
            case 21:
                return "SEARCH";
            case 22:
                return "MKWORKSPACE";
            case 23:
                return "UPDATE";
            case 24:
                return "LABEL";
            case 25:
                return "MERGE";
            case 26:
                return "BASELINE-CONTROL";
            case 27:
                return "MKACTIVITY";
            default:
                return "UNKNOWN";
        }
    }

    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }

    public String getProtocol() {
        return protocol;
    }

    public void setUri(String uri) {
        this.uri = uri;
    }

    public String getUri() {
        return uri;
    }

    public void setRemoteAddr(String remoteAddr) {
        this.remoteAddr = remoteAddr;
    }

    public String getRemoteAddr() {
        return remoteAddr;
    }

    public void setRemoteHost(String remoteHost) {
        this.remoteHost = remoteHost;
    }

    public String getRemoteHost() {
        return remoteHost;
    }

    public void setServerName(String serverName) {
        this.serverName = serverName;
    }

    public String getServerName() {
        return serverName;
    }

    public void setServerPort(int serverPort) {
        this.serverPort = serverPort;
    }

    public int getServerPort() {
        return serverPort;
    }

    public void setSsl(boolean ssl) {
        this.ssl = ssl;
    }

    public boolean isSsl() {
        return ssl;
    }

    public void connect() throws IOException {
        socket = SocketFactory.getDefault().createSocket(host, port);
    }

    public void disconnect() throws IOException {
        socket.close();
        socket = null;
    }

    /*
     * Create a message to request the given URL.
     */
    public TesterAjpMessage createForwardMessage() {

        TesterAjpMessage message = new TesterAjpMessage(packetSize);
        message.reset();

        // Set the header bytes
        message.getBuffer()[0] = 0x12;
        message.getBuffer()[1] = 0x34;

        // Code 2 for forward request
        message.appendByte(Constants.JK_AJP13_FORWARD_REQUEST);

        // HTTP method, GET = 2
        message.appendByte(method);

        // Protocol
        message.appendString(protocol);

        // Request URI
        message.appendString(uri);

        // Client address
        message.appendString(remoteAddr);

        // Client host
        message.appendString(remoteHost);

        // Server name
        message.appendString(serverName);

        // Server port
        message.appendInt(serverPort);

        // Is ssl
        message.appendByte(ssl ? 0x01 : 0x00);

        return message;
    }

    public TesterAjpMessage createBodyMessage(byte[] data) {

        TesterAjpMessage message = new TesterAjpMessage(packetSize);
        message.reset();

        // Set the header bytes
        message.getBuffer()[0] = 0x12;
        message.getBuffer()[1] = 0x34;

        message.appendBytes(data, 0, data.length);
        message.end();

        return message;
    }


    /*
     * Sends an TesterAjpMessage to the server and returns the response message.
     */
    public TesterAjpMessage sendMessage(TesterAjpMessage headers)
            throws IOException {
        return sendMessage(headers, null);
    }

    public TesterAjpMessage sendMessage(TesterAjpMessage headers,
            TesterAjpMessage body) throws IOException {
        // Send the headers
        socket.getOutputStream().write(
                headers.getBuffer(), 0, headers.getLen());
        if (body != null) {
            // Send the body of present
            socket.getOutputStream().write(
                    body.getBuffer(), 0, body.getLen());
        }
        // Read the response
        return readMessage();
    }

    /*
     * Tests the connection to the server and returns the CPONG response.
     */
    public TesterAjpMessage cping() throws IOException {
        // Send the ping message
        socket.getOutputStream().write(AJP_CPING);
        // Read the response
        return readMessage();
    }

    /*
     * Reads a message from the server.
     */
    public TesterAjpMessage readMessage() throws IOException {

        InputStream is = socket.getInputStream();

        TesterAjpMessage message = new TesterAjpMessage(packetSize);

        byte[] buf = message.getBuffer();
        int headerLength = message.getHeaderLength();

        read(is, buf, 0, headerLength);

        int messageLength = message.processHeader(false);
        if (messageLength < 0) {
            throw new IOException("Invalid AJP message length");
        } else if (messageLength == 0) {
            return message;
        } else {
            if (messageLength > buf.length) {
                throw new IllegalArgumentException("Message too long [" +
                        Integer.valueOf(messageLength) +
                        "] for buffer length [" +
                        Integer.valueOf(buf.length) + "]");
            }
            read(is, buf, headerLength, messageLength);
            return message;
        }
    }

    protected boolean read(InputStream is, byte[] buf, int pos, int n)
        throws IOException {

        int read = 0;
        int res = 0;
        while (read < n) {
            res = is.read(buf, read + pos, n - read);
            if (res > 0) {
                read += res;
            } else {
                throw new IOException("Read failed");
            }
        }
        return true;
    }
}
