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.io.File;
import java.util.NoSuchElementException;
import java.util.Objects;

public class SystemController extends BaseController {

    private final SystemService systemService;
    private final SystemCommander systemCommander;

    @Inject
    public SystemController(final Registry registry, final SystemService systemService)
            throws SystemException {
        super("system");
        this.systemService = Objects.requireNonNull(systemService);
        registry.queueInitialMessage(
            makeMessage(
                "online",
                new JsonPrimitive(true),
                QualityOfService.AT_LEAST_ONCE,
                true
            )
        );
        registry.setWill(
            makeMessage(
                "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/open", this::open);
        registry.subscribe(prefix + "commands/run", this::run);

        systemCommander = new SystemCommander();
        systemCommander.parseConfig();
    }

    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.");
        }

        if (systemCommander.isEnabled()) {
            String cmd = systemCommander.getCommand(command);
            if (cmd == null) {
                throw new SystemException("Invalid command: " + command);
            }

            File fp = new File(cmd);
            if (!fp.exists()) {
                throw new SystemException("File not found: " + cmd);
            }
        }

        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);
    }

}

@@ -2226,30 +2226,24 @@
 ) %7B%0A        
-final 
 String comma
@@ -2250,30 +2250,24 @@
 nd;%0A        
-final 
 String param
@@ -2277,30 +2277,24 @@
 rs;%0A        
-final 
 String worki
@@ -2869,18 +2869,24 @@
 String c
-md
+ommander
  = syste
@@ -2934,18 +2934,24 @@
    if (c
-md
+ommander
  == null
@@ -3016,21 +3016,10 @@
 mand
-: %22 + command
+.%22
 );%0A 
@@ -3064,18 +3064,24 @@
 w File(c
-md
+ommander
 );%0A     
@@ -3168,17 +3168,10 @@
 ound
-: %22 + cmd
+.%22
 );%0A 
@@ -3174,32 +3174,66 @@
 );%0A            %7D
+%0A%0A            command = commander;
 %0A        %7D%0A%0A    

Fix whitelist command check