package nxm.sys.lib;

import java.util.Iterator;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;

import nxm.sys.inc.OptionTreeAutoLoaderInterface;

/**
 * This class defines the Service that retrieves the Service Provider
 * Implementation for the OptionTreeAutoloaderInterface
 *
 * @author Juan Velasquez
 * @since NeXtMidas 3.7.1
 */

public class OptionTreeAutoLoaderService {
  /**
   * Defines the OptionTreeAutoLoaderService member variable service as static
   * which ensures only one instance of OptionTreeAutoLoaderService exists.
   */
  private static OptionTreeAutoLoaderService service;
  private ServiceLoader<OptionTreeAutoLoaderInterface> loader;

  /** OptionTreeAutoLoaderService Default Constructor */
  public OptionTreeAutoLoaderService() {
    loader = ServiceLoader.load(OptionTreeAutoLoaderInterface.class);
  }

  /** Defines the GetInstance, which enables other classes controlled
   *  access to the OptionTreeAutoLoaderService member variable service
   *  @return new OptionTreeAutoLoaderService
   */
  public static synchronized OptionTreeAutoLoaderService getInstance() {
    if (service == null) {
      service = new OptionTreeAutoLoaderService();
    }
    return service;
  }

  /** OptionTreePathFromClasspath method uses an iterator to go
   *  through the providers in getting the NeXtMidas option tree name.
   *  It calls a Shell.runCommand to add the option to the NeXtMidas path.
   *  @return option tree name
   */
  public String optionTreePathFromClasspath() {
    String optName = null;
    String pathCmd = "PATH ADD+ ";

    try {
      // Used the service loader to get the iterator for the service provider
      Iterator<OptionTreeAutoLoaderInterface> optionTreeLoader = loader.iterator();
      // loop thru the iterator if we got providers. else return null
      while (optionTreeLoader.hasNext()) {
        // create a variable that points to the provider class object
        OptionTreeAutoLoaderInterface opt = optionTreeLoader.next();
        // get the option name
        optName = opt.getOptionTreeName();
        String optCommand = "OPTION,"+optName+",CLASSPATH";
        Shell.runCommand(Shell.getMidasContext(), optCommand);
        // run the PATH ADD+ <option name> NeXtMidas command
        Shell.runCommand(Shell.getMidasContext(), (pathCmd + optName));
      }
      NeXtMidas nxm = NeXtMidas.getGlobalInstance();
      optName = nxm.getPath();
    } catch(ServiceConfigurationError serviceError) {
      optName = null;
      throw new MidasException("Exception when retrieving service provider for "
          + "OptionTreePathFromClasspath method: ", serviceError);
    }
    return optName;
  }
}
