package com.fatico.winthing.systems.system;

import com.fatico.winthing.common.BaseController;
import com.fatico.winthing.messaging.Message;
import com.fatico.winthing.messaging.QualityOfService;
import com.fatico.winthing.messaging.Registry;
import com.fatico.winthing.windows.SystemException;

import com.google.gson.JsonArray;
import com.google.gson.JsonPrimitive;
import com.google.inject.Inject;

import java.util.NoSuchElementException;
import java.util.Objects;

public class SystemController extends BaseController {

    private final SystemService systemService;

    @Inject
    public SystemController(final Registry registry, final SystemService systemService)
            throws SystemException {
        super("system");
        this.systemService = Objects.requireNonNull(systemService);
        registry.queueInitialMessage(
            makeMessage(
                prefix + "online",
                new JsonPrimitive(true),
                QualityOfService.AT_LEAST_ONCE,
                true
            )
        );
        registry.setWill(
            makeMessage(
                prefix + "online",
                new JsonPrimitive(false),
                QualityOfService.AT_LEAST_ONCE,
                true
            )
        );
        registry.subscribe(prefix + "commands/shutdown", this::shutdown);
        registry.subscribe(prefix + "commands/suspend", this::suspend);
        registry.subscribe(prefix + "commands/hibernate", this::hibernate);
        registry.subscribe(prefix + "commands/reboot", this::reboot);
        registry.subscribe(prefix + "commands/run", this::run);
        registry.subscribe(prefix + "commands/open", this::open);
    }

    public void shutdown(final Message message) {
        systemService.shutdown();
    }

    void reboot(final Message message) {
        systemService.reboot();
    }
    
    public void suspend(final Message message) {
        systemService.suspend();
    }

    public void hibernate(final Message message) {
        systemService.hibernate();
    }

    public void run(final Message message) {
        final String command;
        final String parameters;
        final String workingDirectory;
        try {
            final JsonArray arguments = message.getPayload().get().getAsJsonArray();
            command = arguments.get(0).getAsString();
            parameters = (arguments.size() > 1 ? arguments.get(1).getAsString() : "");
            workingDirectory = (arguments.size() > 2 ? arguments.get(2).getAsString() : null);
        } catch (final NoSuchElementException | IllegalStateException exception) {
            throw new IllegalArgumentException("Invalid arguments.");
        }
        systemService.run(command, parameters, workingDirectory);
    }

    public void open(final Message message) {
        final String uri;
        try {
            uri = message.getPayload().get().getAsString();
        } catch (final NoSuchElementException | IllegalStateException exception) {
            throw new IllegalArgumentException("Invalid arguments.");
        }
        systemService.open(uri);
    }

}

@@ -395,16 +395,37 @@
 nject;%0A%0A
+import java.io.File;%0A
 import j
@@ -457,16 +457,16 @@
 eption;%0A
-
 import j
@@ -586,16 +586,67 @@
 Service;
+%0A    private final SystemCommander systemCommander;
 %0A%0A    @I
@@ -1620,72 +1620,8 @@
 t);%0A
-        registry.subscribe(prefix + %22commands/run%22, this::run);%0A
     
@@ -1678,24 +1678,426 @@
 his::open);%0A
+        %0A        systemCommander = new SystemCommander();%0A        systemCommander.parseConfig();%0A        %0A        if (systemCommander.isEnabled()) %7B%0A        %09for (String command : systemCommander.getList()) %7B%0A        %09%09registry.subscribe(prefix + %22commands/run/%22 + command, this::execute);%09%0A        %09%7D%0A        %7D%0A        else %7B%0A        %09registry.subscribe(prefix + %22commands/run%22, this::run);%0A        %7D%0A
     %7D%0A%0A    p
@@ -3085,32 +3085,32 @@
 s.%22);%0A        %7D%0A
-
         systemSe
@@ -3156,32 +3156,642 @@
 irectory);%0A    %7D
+%0A    %0A    public void execute(final Message message) %7B%0A   %09%09String%5B%5D topics = message.getTopic().split(%22/%22);%0A   %09%09if (topics.length %3E 0) %7B%0A   %09%09%09String topic = topics%5Btopics.length - 1%5D;%0A   %09%09%09for (String command : systemCommander.getList()) %7B%0A   %09%09%09%09if (command.equals(topic)) %7B%0A   %09%09%09%09%09String cmd = systemCommander.getCommand(topic);%0A   %09%09%09%09%09File fp = new File(cmd);%0A   %09%09%09%09%09if (fp.exists()) %7B   %09%09%09%09%09%0A   %09%09%09%09%09%09systemService.run(systemCommander.getCommand(topic), %22%22, null);%0A   %09%09%09%09%09%7D%0A   %09%09%09%09%09else %7B%0A   %09%09%09%09%09%09throw new SystemException(%22Could not run command: %22 + cmd);%0A   %09%09%09%09%09%7D%0A   %09%09%09%09%7D%0A   %09%09%09%7D%0A   %09%09%7D%0A    %7D
 %0A%0A    public voi

Add function for whitelisted commands to execute on local machine