/*
 * 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.royale.test.ant;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.text.MessageFormat;

import org.apache.tools.ant.BuildException;

/**
 * Class responsible for managing the connections to the test runner and any boiler plate in the network interactivity. 
 */
public class RoyaleUnitSocketServer implements IRoyaleUnitServer
{
    
    private static final char NULL_BYTE = '\u0000';
    private static final String POLICY_FILE_REQUEST = "<policy-file-request/>";
    
    //Uncomment to use DTD for validation rather than schema
    //private static final String DOMAIN_POLICY = "<?xml version=\"1.0\"?><!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"{0}\" /></cross-domain-policy>";

    private static final String DOMAIN_POLICY = 
        "<?xml version=\"1.0\"?>"
        + "<cross-domain-policy xmlns=\"http://localhost\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.adobe.com/xml/schemas PolicyFileSocket.xsd\">"
        + "<allow-access-from domain=\"*\" to-ports=\"{0}\" />"
        + "</cross-domain-policy>";
    
    private static final String START_OF_TEST_RUN_ACK = "<startOfTestRunAck/>";
    private static final String END_OF_TEST_RUN_ACK = "<endOfTestRunAck/>";
    
    private int port;
    private int timeout;
    private int inboundBufferSize;  //if this is not set high enough, incoming data may clobber unread data in the buffer
    private boolean waitForPolicyFile;

    private ServerSocket serverSocket = null;
    private Socket clientSocket = null;
    private InputStreamReader inboundReader = null;
    private OutputStreamWriter outboundWriter = null;

    public RoyaleUnitSocketServer(int port, int timeout, int inboundBufferSize, boolean waitForPolicyFile)
    {
        this.port = port;
        this.timeout = timeout;
        this.inboundBufferSize = inboundBufferSize;
        this.waitForPolicyFile = waitForPolicyFile;
    }

    /**
     * Starts the socket server, managing policy file requests, and starting the test process.
     */
    public void start() throws IOException
    {
        LoggingUtil.log("Starting server ...");
        
        try
        {
            openServerSocket();
            openClientSocket();
            prepareClientSocket();
        }
        catch (SocketTimeoutException e)
        {
            throw new BuildException("Socket timeout waiting for royaleunit report", e);
        }
    }

    public boolean isPending()
    {
        return false;
    }

    public Exception getException()
    {
        return null;
    }
    
    /**
     * Resets the client connection.
     */
    private void resetInboundStream() throws IOException
    {
        LoggingUtil.log("Resetting client connection ...");
        
        closeClientSocket();
        openClientSocket();
    }
    
    /**
     * Creates a connection on the specified socket. Waits {socketTimeout}
     * seconds for a client connection before throwing an error
     */
    private void openServerSocket() throws IOException
    {
        serverSocket = new ServerSocket(port);
        serverSocket.setSoTimeout(timeout);

        LoggingUtil.log("Opening server socket on port [" + port + "].");
    }

    /**
     * Creates the client connection. This method will pause until the connection
     * is made or the timout limit is reached.
     * 
     * Once a connection is established opens the in and out buffer.
     */
    private void openClientSocket() throws IOException
    {
        LoggingUtil.log("Waiting for client connection ...");
        
        // This method blocks until a connection is made.
        clientSocket = serverSocket.accept();

        LoggingUtil.log("Client connected.");
        LoggingUtil.log("Setting inbound buffer size to [" + inboundBufferSize + "] bytes.");
        
        inboundReader = new InputStreamReader(new BufferedInputStream(clientSocket.getInputStream(), inboundBufferSize), "UTF-8");
        outboundWriter = new OutputStreamWriter(new BufferedOutputStream(clientSocket.getOutputStream()), "UTF-8");
        
        LoggingUtil.log("Receiving data ...");
    }
    
    /**
     * Decides whether to send a policy request or a start ack
     */
    private void prepareClientSocket() throws IOException
    {
        // if it's a policy request, make sure the first thing we send is a policy response
        if (waitForPolicyFile)
        {
            String request = readNextTokenFromSocket();
            if (request.equals(POLICY_FILE_REQUEST))
            {
                LoggingUtil.log("Policy file requested.");
                
                sendPolicyFile();
                resetInboundStream();
            }
        }

        //tell client to start the testing process
        sendTestRunStartAcknowledgement();
    }
    
    /**
     * Generate domain policy message and send 
     */
    private void sendPolicyFile() throws IOException
    {
        sendOutboundMessage(MessageFormat.format(DOMAIN_POLICY, new Object[] { Integer.toString(port) }));

        LoggingUtil.log("Policy file sent.");
    }

    /**
     * Generate and send message to inform test runner to begin sending test data
     */
    private void sendTestRunStartAcknowledgement() throws IOException
    {
        LoggingUtil.log("Sending acknowledgement to player to start sending test data ...\n");
        
        sendOutboundMessage(START_OF_TEST_RUN_ACK);
    }
    
    /**
     * Reads tokens from the socket input stream based on NULL_BYTE as a delimiter
     */
    public String readNextTokenFromSocket() throws IOException
    {
        StringBuffer buffer = new StringBuffer();
        int piece = -1;

        while ((piece = inboundReader.read()) != NULL_BYTE)
        {
            //Did we reach the end of the buffer?  Tell the user there is nothing more.
            if (piece == -1)
            {
                return null;
            }

            final char chr = (char) piece;
            buffer.append(chr);
        }

        //Did we recieve a message that the test run is over? Tell the user we have nothing more.
        String token = buffer.toString();
        
        return token;
    }
    
    private void sendOutboundMessage(String message) throws IOException
    {
        if(outboundWriter != null)
        {
            outboundWriter.write(message);
            outboundWriter.write(NULL_BYTE);
            outboundWriter.flush();
        }
    }

    /**
     * Stops the socket server, notifying the test runner, and closing the appropriate connections.
     */
    public void stop() throws IOException, InterruptedException
    {
        LoggingUtil.log("\nStopping server ...");
        
        sendTestRunEndAcknowledgement();
        closeClientSocket();
        closeServerSocket();
    }
    
    /**
     * Sends the end of test run to the listener to close the connection
     */
    private void sendTestRunEndAcknowledgement() throws IOException
    {
        LoggingUtil.log("End of test data reached, sending acknowledgement to player ...");
        
        sendOutboundMessage(END_OF_TEST_RUN_ACK);
    }
    
    /**
     * Closes the client connection and all buffers, ignoring any errors
     */
    private void closeClientSocket() throws IOException
    {
        LoggingUtil.log("Closing client connection ...");
        
        // Close the output stream.
        if (outboundWriter != null)
        {
            outboundWriter.close();
        }

        // Close the input stream.
        if (inboundReader != null)
        {
            inboundReader.close();
        }

        // Close the client socket.
        if (clientSocket != null)
        {
            clientSocket.close();
        }
    }

    /**
     * Closes the server socket. Ignores any errors if unable to close
     */
    private void closeServerSocket() throws IOException
    {
        LoggingUtil.log("Closing server on port [" + port + "] ...");
        
        if (serverSocket != null)
        {
            serverSocket.close();
        }
    }
}
