/**
 * Copyright Notice
 *
 * This is a work of the U.S. Government and is not subject to copyright
 * protection in the United States. Foreign copyrights may apply.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package gov.va.isaac;

import gov.va.isaac.interfaces.gui.ApplicationWindowI;
import gov.va.isaac.interfaces.gui.CommonDialogsI;
import gov.va.isaac.interfaces.gui.views.PopupConceptViewI;
import gov.va.oia.HK2Utilities.HK2RuntimeInitializerCustom;
import java.io.IOException;
import java.lang.annotation.Annotation;
import org.glassfish.hk2.api.ServiceLocator;

/**
 * AppContext
 *
 * Provides convenience methods for retrieving implementations of various interfaces
 * from the HK2 dependency management system.
 *
 * @author <a href="mailto:daniel.armbrust.list@gmail.com">Dan Armbrust</a>
 */
public class AppContext
{
	private static ServiceLocator serviceLocator_;
	private static AppProperties appProperties_;

	/**
	 * Call this once (and only once) to initialize the ISAAC HK2 service Locator.
	 * After this is called, you can access the service locator via convenience methods here,
	 * or via a call directly to HK2:
	 * {@code
	 *     ServiceLocatorFactory.getInstance().create("ISAAC");
	 * }
	 * @throws IOException
	 * @throws ClassNotFoundException
	 *
	 */
	public synchronized static void setup() throws ClassNotFoundException, IOException
	{
		if (serviceLocator_ != null)
		{
			throw new RuntimeException("Only one service locator should be set");
		}
		serviceLocator_ = HK2RuntimeInitializerCustom.init("ISAAC", false, "gov.va", "org.ihtsdo");

		appProperties_ = new AppProperties();
	}

	public static AppProperties getAppProperties()
	{
		return appProperties_;
	}

	public static ServiceLocator getServiceLocator()
	{
		return serviceLocator_;
	}

	public static <T> T getService(Class<T> contractOrService, Annotation... qualifiers)
	{
		return serviceLocator_.getService(contractOrService, qualifiers);
	}
	
	public static <T> T getService(Class<T> contractOrService, String name, Annotation... qualifiers)
	{
		return serviceLocator_.getService(contractOrService, name, qualifiers);
	}

	public static CommonDialogsI getCommonDialogs()
	{
		return getService(CommonDialogsI.class);
	}

	public static ApplicationWindowI getMainApplicationWindow()
	{
		return getService(ApplicationWindowI.class);
	}

	public static PopupConceptViewI createConceptViewWindow()
	{
		return getService(PopupConceptViewI.class, "LegacyStyle");
	}
}

@@ -1078,16 +1078,48 @@
 Locator;
+%0Aimport org.slf4j.LoggerFactory;
 %0A%0A/**%0A *
@@ -2488,16 +2488,504 @@
 );%0A%09%7D%0A%09%0A
+%09/**%0A%09 * Find a service by name, and automatically fall back to any service which implements the contract if the named service was not available.%0A     * @param contractOrService May not be null, and is the contract or concrete implementation to get the best instance of%0A     * @param name May be null (to indicate any name is ok), and is the name of the implementation to be returned%0A     * @param qualifiers The set of qualifiers that must match this service definition%0A%09 * @return%0A%09 */%0A
 %09public 
@@ -3072,38 +3072,43 @@
 ualifiers)%0A%09%7B%0A%09%09
-return
+T service =
  serviceLocator_
@@ -3153,24 +3153,338 @@
 ualifiers);%0A
+%09%09if (service == null && name != null)%0A%09%09%7B%0A%09%09%09LoggerFactory.getLogger(AppContext.class).info(%22Requested service '%22 + name + %22' was not available, returning arbitrary service %22 +%0A%09%09%09%09%09%22which matches the contract (if any)%22);%0A%09%09%09return serviceLocator_.getService(contractOrService, qualifiers);%0A%09%09%7D%0A%09%09return service;%0A
 %09%7D%0A%0A%09public 

Add an auto-fallback option to service lookup by name.