/*
 * 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.sling.maven.slingstart.feature.run;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Control listener.
 * This class listens for the startup of a launchpad instance.
 */
public class ControlListener implements Runnable {

    // command sent by the client to notify startup
    private static final String COMMAND_STARTED = "started";

    private static final String RESPONSE_OK = "ok";

    // The default interface to listen on
    private static final String DEFAULT_LISTEN_INTERFACE = "127.0.0.1";

    // The port to listen on
    private final int port;

    private volatile boolean started = false;

    private volatile boolean stopped = false;

    private volatile ServerSocket server;

    public ControlListener(final int p) {
        this.port = p;
        final Thread listener = new Thread(this);
        listener.setDaemon(true);
        listener.setName("Launchapd startup listener");
        listener.start();
    }

    public int getPort() {
        return this.port;
    }

    public boolean isStarted() {
        return this.started;
    }

    public void stop() {
        stopped = true;
        if ( server != null ) {
            try {
                server.close();
            } catch (IOException e) {
                // ignore
            }
        }
    }

    /**
     * Implements the server thread receiving commands from clients and acting
     * upon them.
     */
    @Override
    public void run() {
        final InetSocketAddress socketAddress = getSocketAddress(this.port);
        try {
            server = new ServerSocket();
            server.bind(socketAddress);
        } catch (final IOException ioe) {
            return;
        }

        try {
            while (!stopped) {

                final Socket s = server.accept();

                try {
                    final String commandLine = readLine(s);
                    if (commandLine == null) {
                        final String msg = "ERR: missing command";
                        writeLine(s, msg);
                        continue;
                    }

                    final String command = commandLine;

                    if (COMMAND_STARTED.equals(command)) {
                        writeLine(s, RESPONSE_OK);
                        this.started = true;
                        this.stopped = true;
                        break;

                    } else {
                        final String msg = "ERR:" + command;
                        writeLine(s, msg);

                    }
                } finally {
                    try {
                        s.close();
                    } catch (IOException ignore) {
                    }
                }
            }
        } catch (final IOException ioe) {
            // ignore
        } finally {
            try {
                server.close();
            } catch (final IOException ignore) {
                // ignore
            }
        }
    }

    private String readLine(final Socket socket) throws IOException {
        final BufferedReader br = new BufferedReader(new InputStreamReader(
            socket.getInputStream(), "UTF-8"));
        return br.readLine();
    }

    private void writeLine(final Socket socket, final String line) throws IOException {
        final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
            socket.getOutputStream(), "UTF-8"));
        bw.write(line);
        bw.write("\r\n");
        bw.flush();
    }

    private static InetSocketAddress getSocketAddress(final int port) {
        final String address = DEFAULT_LISTEN_INTERFACE;

        final InetSocketAddress addr = new InetSocketAddress(address, port);
        if (!addr.isUnresolved()) {
            return addr;
        }

        return null;
    }
}
