package leigh.astro.indi;

import leigh.astro.indi.base.Constants;
import leigh.astro.indi.client.INDIDevice;
import leigh.astro.indi.client.INDIServerConnection;
import leigh.astro.indi.client.INDIServerConnectionListener;
import leigh.astro.indi.protocol.url.INDIURLStreamHandlerFactory;
import leigh.mecha.log.MechaLogger;
import leigh.mecha.log.MechaLoggerFactory;

import java.io.IOException;
import java.util.Date;

public class AstroClient implements INDIServerConnectionListener {
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(AstroClient.class);

    static {
        INDIURLStreamHandlerFactory.init();
    }

    private INDIServerConnection currentConnection;

    public AstroClient(String host, int port) {
        currentConnection = new INDIServerConnection(host, port);

        // Listen to all server events
        currentConnection.addINDIServerConnectionListener(this);

        try {
            currentConnection.connect();
            currentConnection.askForDevices(); // Ask for all the devices.
        } catch (IOException e) {
            logger.error("Problem with the connection: " + host + ":" + port, e);
        }
    }

    public static void main(String[] args) {
        if (args.length < 1 || args.length > 2) {
            printErrorMessageAndExit();
        }

        String host = args[0];
        int port = Constants.INDI_DEFAULT_PORT;

        if (args.length > 1) {
            try {
                port = Integer.parseInt(args[1]);
            } catch (NumberFormatException e) {
                printErrorMessageAndExit();
            }
        }

        new AstroClient(host, port);
    }

    private static void printErrorMessageAndExit() {
        System.out.println("The program must be called in the following way:");

        System.out.println("> java SimpleINDIClient host [port]\n  where");
        System.out.println("    host - is the INDI Server to connect to");
        System.out.println("    port - is the INDI Server port. If not present the default port (" +
                Constants.INDI_DEFAULT_PORT + ") will be used.\n");

        System.exit(-1);
    }

    @Override
    public void newDevice(INDIServerConnection connection, INDIDevice device) {
        // We just simply listen to this Device
        System.out.println("New device: " + device.getName());

        // Enable receiving BLOBs from this Device
        try {
            device.blobsEnable(Constants.BLOBEnables.ALSO);
        } catch (IOException e) {
            e.printStackTrace();
        }

        device.addINDIDeviceListener(new DebugListener(device));
    }

    @Override
    public void removeDevice(INDIServerConnection connection, INDIDevice device) {
        // We just remove ourselves as a listener of the removed device
        System.out.println("Device Removed: " + device.getName());
    }

    @Override
    public void connectionLost(INDIServerConnection connection) {
        System.out.println("Connection lost. Bye");

        System.exit(-1);
    }

    @Override
    public void newMessage(INDIServerConnection connection, Date timestamp, String message) {
        System.out.println("New Server Message: " + timestamp + " - " + message);
    }
}
