package seedu.taskell.logic.commands;

import java.io.IOException;
import java.util.logging.Logger;

import seedu.taskell.commons.core.Config;
import seedu.taskell.commons.core.EventsCenter;
import seedu.taskell.commons.core.LogsCenter;
import seedu.taskell.commons.events.model.TaskManagerChangedEvent;
import seedu.taskell.commons.events.storage.StorageLocationChangedEvent;
import seedu.taskell.model.ReadOnlyTaskManager;
import seedu.taskell.storage.JsonConfigStorage;

/** Saves current data file to new filepath.
 * */

public class SaveStorageLocationCommand extends Command {
    
    private Logger logger = LogsCenter.getLogger(SaveStorageLocationCommand.class.getName());
    
    public static final String COMMAND_WORD = "save";

    public static final String MESSAGE_USAGE = COMMAND_WORD + ": Saves data file to new location specified.\n"
            + "Parameters: FILEPATH (must be valid and already present on computer)\n"
            + "Example: " + COMMAND_WORD + "C:/Users/chicken/Desktop/cat";
    
    private static final String MESSAGE_SUCCESS = "Data successfully saved to new location.";
    private static final String MESSAGE_INVALID_PATH = "Filepath given is invalid.";
    
    private static Config config;
    private String newStorageFilePath;
    private ReadOnlyTaskManager taskManager;
    private static JsonConfigStorage jsonConfigStorage;
    
    public SaveStorageLocationCommand(String newStorageFilePath) {
        this.newStorageFilePath = newStorageFilePath.trim().replace("\\", "/") + "/taskmanager.xml";
        logger.severe("New file path" + newStorageFilePath);
        jsonConfigStorage = new JsonConfigStorage(Config.DEFAULT_CONFIG_FILE);
    }
    
    public static void setConfig(Config c) {
        config = c;
    }

    @Override
    public CommandResult execute() {
        assert config != null;
        assert jsonConfigStorage != null;

        taskManager = model.getTaskManager();
        config.setTaskManagerFilePath(newStorageFilePath);
        indicateStorageLocationChanged();
        
        try {
            indicateTaskManagerChanged();
        } catch (Exception e) {
            return new CommandResult(MESSAGE_INVALID_PATH);
        }
        
        try {
            jsonConfigStorage.saveConfigFile(config);
        } catch (IOException e) {
            logger.severe("save to config json error");
        }
        return new CommandResult(MESSAGE_SUCCESS);
    }

    private void indicateStorageLocationChanged() {
        assert config != null;
        EventsCenter.getInstance().post(new StorageLocationChangedEvent(config));
    }
    
    private void indicateTaskManagerChanged() {
        assert taskManager != null;
        EventsCenter.getInstance().post(new TaskManagerChangedEvent(taskManager));
    }

}

@@ -234,75 +234,8 @@
 er;%0A
-import seedu.taskell.commons.events.model.TaskManagerChangedEvent;%0A
 impo
@@ -398,16 +398,54 @@
 Storage;
+%0Aimport seedu.taskell.storage.Storage;
 %0A%0A/** Sa
@@ -814,16 +814,100 @@
 ecified.
+ %22%0A            + %22New files can be auto-created as long as given directory is valid.
 %5Cn%22%0A    
@@ -956,40 +956,8 @@
 alid
- and already present on computer
 )%5Cn%22
@@ -1001,16 +1001,17 @@
 WORD + %22
+ 
 C:/Users
@@ -1214,16 +1214,52 @@
 invalid.
+ Filepath will be reset to old path.
 %22;%0A    %0A
@@ -1329,16 +1329,36 @@
 FilePath
+, oldStorageFilePath
 ;%0A    pr
@@ -1452,16 +1452,52 @@
 torage;%0A
+    private static Storage storage;%0A
     %0A   
@@ -1556,24 +1556,161 @@
 FilePath) %7B%0A
+        this.oldStorageFilePath = config.getTaskManagerFilePath();%0A        logger.info(%22Old file path: %22 + oldStorageFilePath);%0A        %0A
         this
@@ -1813,22 +1813,20 @@
  logger.
-severe
+info
 (%22New fi
@@ -1832,20 +1832,27 @@
 ile path
+: 
 %22 + 
+this.
 newStora
@@ -2020,24 +2020,103 @@
 g = c;%0A    %7D
+%0A    %0A    public static void setStorage(Storage s) %7B%0A        storage = s;%0A    %7D
 %0A%0A    @Overr
@@ -2272,24 +2272,33 @@
 kManager();%0A
+        %0A
         conf
@@ -2382,33 +2382,24 @@
 nChanged();%0A
-        %0A
         try 
@@ -2412,23 +2412,27 @@
         
-indicat
+storage.sav
 eTaskMan
@@ -2435,24 +2435,48 @@
 kManager
-Ch
+(taskM
 an
+a
 ge
-d(
+r, newStorageFilePath
 );%0A     
@@ -2487,16 +2487,18 @@
  catch (
+IO
 Exceptio
@@ -2496,32 +2496,78 @@
 OException e) %7B%0A
+            handleInvalidFilePathException();%0A
             retu
@@ -2641,167 +2641,27 @@
     
-try %7B%0A            jsonConfigStorage.
 save
+To
 Config
-File(config);%0A        %7D catch (IOException e) %7B%0A            logger.severe(%22save to config json error%22);%0A        %7D
+Json();
 %0A   
@@ -2912,36 +2912,313 @@
 oid 
-indicateTaskManagerChanged()
+handleInvalidFilePathException() %7B%0A        logger.info(%22Error writing to filepath. Handling data save exception.%22);%0A        assert config != null;%0A        %0A        config.setTaskManagerFilePath(oldStorageFilePath);  //set back to old filepath%0A        indicateStorageLocationChanged();%0A        %0A        try
  %7B%0A 
@@ -3228,118 +3228,423 @@
     
-assert taskManager != null;%0A        EventsCenter.getInstance().post(new TaskM
+    storage.saveTaskManager(taskManager, newStorageFilePath);%0A        %7D catch (IOException e) %7B%0A            logger.severe(%22Error saving task m
 anager
-ChangedEvent(taskManager));
+%22);%0A        %7D%0A        %0A        saveToConfigJson();%0A    %7D%0A    %0A    private void saveToConfigJson() %7B%0A        try %7B%0A            jsonConfigStorage.saveConfigFile(config);%0A        %7D catch (IOException e) %7B%0A            logger.severe(%22save to config json error%22);%0A        %7D
 %0A   

edit SaveStorageLocation logic sequence of saving data and writing to config.json also add error handling for invalid filepath