/*
 *Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *WSO2 Inc. 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.wso2.carbon.esb.tcp.transport.test.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * Java client for TCP transport.
 */
public class NativeTCPClient {

    private String host = "localhost";
    private Socket socket = null;
    private int messageCount = 0;
    private String delimiterType;
    private String stringDelimiter;
    private Character byteDelimiter;
    private String characterDelimiter;
    private String message;

    public NativeTCPClient(String delimiterType, int messageCount, int port) throws IOException {
        this.socket = new Socket(this.host, port);
        this.messageCount = messageCount;
        this.delimiterType = delimiterType;
    }

    public void sendToServer() throws Exception {
        PrintWriter outToServer = null;
        outToServer = new PrintWriter(new OutputStreamWriter(this.socket.getOutputStream()));
        String message = "";
        StringBuilder fullMessage = new StringBuilder(message);
        for (int i = 0; i < this.messageCount; ++i) {
            fullMessage.append(this.message);
            if (DelimiterTypeEnum.BYTE.getDelimiterType().equalsIgnoreCase(this.delimiterType)) {
                fullMessage.append(this.byteDelimiter);
            } else if (DelimiterTypeEnum.CHARACTER.getDelimiterType().equalsIgnoreCase(this.delimiterType)) {
                fullMessage.append(this.characterDelimiter);
            } else {
                fullMessage.append(this.stringDelimiter);
            }
        }
        outToServer.print(fullMessage);
        outToServer.flush();
    }

    public String[] receiveCharactorTypeDelimiterResonse() throws Exception {
        //Wait for some time to get server response
        Thread.sleep(3000);
        char delimiter = 0;
        ByteArrayOutputStream bos = null;
        if (DelimiterTypeEnum.BYTE.getDelimiterType().equalsIgnoreCase(this.delimiterType)) {
            delimiter = this.byteDelimiter;
        } else if (DelimiterTypeEnum.CHARACTER.getDelimiterType().equalsIgnoreCase(this.delimiterType)) {
            delimiter = this.characterDelimiter.charAt(0);
        }

        if (delimiter == 0) {
            throw new Exception("Delimiter has not specified");
        } else {
            String[] responses;
            try {
                responses = new String[this.messageCount];
                InputStream stream = this.socket.getInputStream();
                int tempMessageCount = 0;
                int next = stream.read();
                bos = new ByteArrayOutputStream();
                while (next > -1) {
                    if (delimiter != next) {
                        bos.write(next);
                    }
                    next = stream.read();
                    if (delimiter == next) {
                        responses[tempMessageCount] = new String(bos.toByteArray());
                        ++tempMessageCount;
                        if (tempMessageCount == this.messageCount) {
                            break;
                        }
                        bos = new ByteArrayOutputStream();
                    }
                }
            } finally {
                try {
                    this.closeSocket();
                } catch (IOException var12) {
                    //ignore
                }
                if (bos != null) {
                    bos.close();
                }
            }
            return responses;
        }
    }

    public String[] receiveStringTypeDelimiterResonse() throws Exception {
        ByteArrayOutputStream bos = null;
        Thread.sleep(3000);
        try {
            InputStream stream = this.socket.getInputStream();
            int next = stream.read();
            bos = new ByteArrayOutputStream();
            while (true) {
                if (next > -1) {
                    bos.write(next);
                    if (stream.available() > 0) {
                        next = stream.read();
                        continue;
                    }
                }

                String[] responses = (new String(bos.toByteArray())).split(this.stringDelimiter);
                return responses;
            }
        } finally {
            try {
                this.closeSocket();
            } catch (IOException var10) {
                //ignore
            }
            if (bos != null) {
                bos.close();
            }
        }
    }

    void closeSocket() throws IOException {
        this.socket.close();
    }

    public String getDelimiterType() {
        return this.delimiterType;
    }

    public void setDelimiterType(String delimiterType) {
        this.delimiterType = delimiterType;
    }

    public String getStringDelimiter() {
        return this.stringDelimiter;
    }

    public void setStringDelimiter(String stringDelimiter) {
        this.stringDelimiter = stringDelimiter;
    }

    public String getCharacterDelimiter() {
        return this.characterDelimiter;
    }

    public void setCharacterDelimiter(String characterDelimiter) {
        this.characterDelimiter = characterDelimiter;
    }

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public void setByteDelimiter(Character byteDelimiter) {
        this.byteDelimiter = byteDelimiter;
    }

    public static enum DelimiterTypeEnum {
        STRING("STRING"), CHARACTER("CHARACTER"), BYTE("BYTE");

        private final String delimiterType;

        private DelimiterTypeEnum(String delimiterType) {
            this.delimiterType = delimiterType;
        }

        public String getDelimiterType() {
            return this.delimiterType;
        }
    }
}