/**
 * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.component;

import java.net.InetAddress;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.SocketException;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CommandMonitor extends Thread {
  private static final Logger s_logger = LoggerFactory.getLogger(ComponentManager.class);
  private static final String SECRET_PROPERTY="commandmonitor.secret";
  private static final String PORT_PROPERTY="commandmonitor.port";
  private static final String DEFAULT_SECRET="OpenGamma";
  private static final int DEFAULT_PORT=8079;
  private static final int COMMAND_LENGTH=256;

  private ComponentRepository _repo;
  private String _secret;
  private int _port;
  private DatagramSocket _socket;

  private CommandMonitor(ComponentRepository repo, String secret, int port) {
    _repo = repo;
    _secret = secret;
    _port = port;

    setDaemon(true);
    setName("CommandMonitor");
    try {
      _socket = new DatagramSocket(port, InetAddress.getLoopbackAddress());
    } catch (SocketException e) {
      s_logger.warn("Failed to create listening socket, CommandMonitor will not be available");
      return;
    }

    this.start();
  }

  @Override
  public void run() {
    while(true) {
      byte[] buffer = new byte[COMMAND_LENGTH];
      DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
      try {
      _socket.receive(packet);
      } catch (IOException e) {
        s_logger.warn("Error while receiving command packet");
        continue;
      }
      String received = new String(packet.getData(), 0, packet.getLength());

      if(!received.matches("secret:"+_secret+"\\s+command:\\w+\\s*")) {
        s_logger.debug("Malformed command or wrong secret");
        continue;
      }

      String command=received.replaceAll("secret:"+_secret+"\\s+command:(\\w+)\\s*","$1");
      s_logger.debug("Received command \"{}\"", command);

      if(command.equals("stop")) {
        /* What do we do if the repo isn't running? */
        if(_repo.isRunning()) {
          _repo.stop();
        }
      } else if(command.equals("exit")) {
        if(_repo.isRunning()) {
          _repo.stop();
        }
        System.exit(0);
      } else {
        s_logger.debug("Unknown command \"{}\"", command);
      }
    }
  }

  public static void create(ComponentRepository repo) {
    String secret = System.getProperty(SECRET_PROPERTY, DEFAULT_SECRET);
    String port = System.getProperty(PORT_PROPERTY, Integer.toString(DEFAULT_PORT));
    new CommandMonitor(repo, secret, Integer.parseInt(port));
  }

  public static void create(ComponentRepository repo, String secret, int port) {
    new CommandMonitor(repo, secret, port);
  }

  public static void main(String[] args) throws IOException {
    byte[] buffer = new byte[COMMAND_LENGTH];
    InetAddress address = InetAddress.getLoopbackAddress();

    String secret = System.getProperty(SECRET_PROPERTY, DEFAULT_SECRET);
    String port = System.getProperty(PORT_PROPERTY, Integer.toString(DEFAULT_PORT));
    String command = (args.length==1)?args[0]:"exit";

    String toSend = "secret:" + secret + " command:" + command + "\n";
    byte[] sBuffer = toSend.getBytes();

    System.out.println("Sending "+toSend);
    try {
      DatagramSocket socket = new DatagramSocket();
      DatagramPacket packet = new DatagramPacket(sBuffer, sBuffer.length, address, Integer.parseInt(port));
      socket.send(packet);
    } catch (Exception e) {
      System.out.println("Send failed...");
    }
  }
}

@@ -181,23 +181,22 @@
 ava.
-net.InetAddress
+io.IOException
 ;%0Aim
@@ -213,26 +213,26 @@
 net.Datagram
-So
+Pa
 cket;%0Aimport
@@ -241,34 +241,34 @@
 ava.net.Datagram
-Pa
+So
 cket;%0Aimport jav
@@ -277,52 +277,21 @@
 net.
-SocketException;%0Aimport java.io.IOException;
+InetAddress;%0A
 %0Aimp
@@ -345,23 +345,41 @@
 ctory;%0A%0A
+/**%0A * %0A */%0A
 public 
+final 
 class Co
@@ -535,33 +535,35 @@
  SECRET_PROPERTY
-=
+ = 
 %22commandmonitor.
@@ -614,17 +614,19 @@
 PROPERTY
-=
+ = 
 %22command
@@ -684,17 +684,19 @@
 T_SECRET
-=
+ = 
 %22OpenGam
@@ -739,17 +739,19 @@
 ULT_PORT
-=
+ = 
 8079;%0A  
@@ -789,17 +789,19 @@
 D_LENGTH
-=
+ = 
 256;%0A%0A  
@@ -1174,29 +1174,23 @@
 ss.getLo
-opbackAddress
+calHost
 ());%0A   
@@ -1199,22 +1199,18 @@
  catch (
-Socket
+IO
 Exceptio
@@ -1399,16 +1399,17 @@
    while
+ 
 (true) %7B
@@ -1513,16 +1513,17 @@
 (buffer,
+ 
 buffer.l
@@ -1534,32 +1534,34 @@
 h);%0A      try %7B%0A
+  
       _socket.re
@@ -1782,16 +1782,17 @@
       if
+ 
 (!receiv
@@ -1807,33 +1807,37 @@
 es(%22secret:%22
-+
+ + 
 _secret
-+
+ + 
 %22%5C%5Cs+command
@@ -1959,17 +1959,19 @@
  command
-=
+ = 
 received
@@ -1995,17 +1995,21 @@
 et:%22
-+
+ + 
 _secret
-+
+ + 
 %22%5C%5Cs
@@ -2029,16 +2029,17 @@
 +)%5C%5Cs*%22,
+ 
 %22$1%22);%0A 
@@ -2104,16 +2104,17 @@
       if
+ 
 (command
@@ -2189,32 +2189,33 @@
 g? */%0A        if
+ 
 (_repo.isRunning
@@ -2269,16 +2269,17 @@
  else if
+ 
 (command
@@ -2307,16 +2307,17 @@
       if
+ 
 (_repo.i
@@ -2953,16 +2953,27 @@
 eption %7B
+ //CSIGNORE
 %0A    byt
@@ -3058,21 +3058,15 @@
 etLo
-opbackAddress
+calHost
 ();%0A
@@ -3261,21 +3261,27 @@
 ngth
+ 
 ==
+ 
 1)
-?
+ ? 
 args%5B0%5D
-:
+ : 
 %22exi
@@ -3430,17 +3430,19 @@
 ending %22
-+
+ + 
 toSend);

Fix compilation and checkstyle errors.