// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root.

package com.microsoft.alm.plugin.idea.common.services;

import com.intellij.openapi.application.ApplicationManager;
import com.microsoft.alm.plugin.idea.common.settings.SettingsChangedNotifier;
import com.microsoft.alm.plugin.idea.common.settings.TeamServicesSettingsService;
import com.microsoft.alm.plugin.services.PropertyService;

import java.util.Collections;
import java.util.Map;

public class PropertyServiceImpl implements PropertyService {
    private boolean restored = false;
    private Map<String, String> map;

    private static class Holder {
        private static final PropertyServiceImpl INSTANCE = new PropertyServiceImpl();
    }

    /**
     * This constructor is protected to allow for testing
     */
    protected PropertyServiceImpl() {
    }

    public static PropertyServiceImpl getInstance() {
        return Holder.INSTANCE;
    }

    @Override
    public String getProperty(final String propertyName) {
        ensureRestored();
        return map.get(propertyName);
    }

    @Override
    public void setProperty(final String propertyName, final String value) {
        ensureRestored();
        if (value == null) {
            removeProperty(propertyName);
        } else {
            map.put(propertyName, value);
        }

        SettingsChangedNotifier settingsChangedNotifier = ApplicationManager.getApplication().getMessageBus()
                .syncPublisher(SettingsChangedNotifier.SETTINGS_CHANGED_TOPIC);
        settingsChangedNotifier.afterSettingsChanged(propertyName);
    }

    @Override
    public void removeProperty(final String propertyName) {
        if (map.containsKey(propertyName)) {
            map.remove(propertyName);
        }
    }

    public Map<String, String> getProperties() {
        if (map == null) {
            return null;
        }

        return Collections.unmodifiableMap(map);
    }

    private void ensureRestored() {
        if (!restored) {
            restored = true;
            map = TeamServicesSettingsService.getInstance().restoreProperties();
        }
    }
}

@@ -171,16 +171,69 @@
 vices;%0A%0A
+import com.intellij.openapi.application.Application;%0A
 import c
@@ -1428,32 +1428,189 @@
 ue);%0A        %7D%0A%0A
+        Application application = ApplicationManager.getApplication();%0A        if (application == null) // can happen in the unit tests%0A            return;%0A%0A
         Settings
@@ -1651,39 +1651,17 @@
 ifier = 
-ApplicationManager.getA
+a
 pplicati
@@ -1662,18 +1662,16 @@
 lication
-()
 .getMess
@@ -1912,57 +1912,8 @@
 ) %7B%0A
-        if (map.containsKey(propertyName)) %7B%0A    
     
@@ -1942,26 +1942,16 @@
 yName);%0A
-        %7D%0A
     %7D%0A%0A 

Update PropertyServiceImpl to not fail during tests