package org.jivesoftware.smack.provider;

import java.io.InputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

public class ProviderFileLoader implements ProviderLoader {
   private static final Logger LOGGER = Logger.getLogger(ProviderFileLoader.class.getName());
   private final Collection<IQProviderInfo> iqProviders;
   private final Collection<ExtensionProviderInfo> extProviders;
   private final Collection<StreamFeatureProviderInfo> sfProviders;
   private List<Exception> exceptions;

   public ProviderFileLoader(InputStream providerStream) {
      this(providerStream, ProviderFileLoader.class.getClassLoader());
   }

   public ProviderFileLoader(InputStream providerStream, ClassLoader classLoader) {
      this.iqProviders = new LinkedList();
      this.extProviders = new LinkedList();
      this.sfProviders = new LinkedList();
      this.exceptions = new LinkedList();

      try {
         XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
         parser.setFeature("http://xmlpull.org/v1/doc/features.html#process-namespaces", true);
         parser.setInput(providerStream, "UTF-8");
         int eventType = parser.getEventType();

         do {
            if (eventType == 2) {
               String typeName = parser.getName();

               try {
                  if (!"smackProviders".equals(typeName)) {
                     parser.next();
                     parser.next();
                     String elementName = parser.nextText();
                     parser.next();
                     parser.next();
                     String namespace = parser.nextText();
                     parser.next();
                     parser.next();
                     String className = parser.nextText();

                     try {
                        Class<?> provider = classLoader.loadClass(className);
                        byte var11 = -1;
                        switch(typeName.hashCode()) {
                        case -797518000:
                           if (typeName.equals("extensionProvider")) {
                              var11 = 1;
                           }
                           break;
                        case 80611175:
                           if (typeName.equals("streamFeatureProvider")) {
                              var11 = 2;
                           }
                           break;
                        case 1834143545:
                           if (typeName.equals("iqProvider")) {
                              var11 = 0;
                           }
                        }

                        switch(var11) {
                        case 0:
                           if (IQProvider.class.isAssignableFrom(provider)) {
                              this.iqProviders.add(new IQProviderInfo(elementName, namespace, (IQProvider)provider.newInstance()));
                           } else {
                              this.exceptions.add(new IllegalArgumentException(className + " is not a IQProvider"));
                           }
                           break;
                        case 1:
                           if (ExtensionElementProvider.class.isAssignableFrom(provider)) {
                              this.extProviders.add(new ExtensionProviderInfo(elementName, namespace, (ExtensionElementProvider)provider.newInstance()));
                           } else {
                              this.exceptions.add(new IllegalArgumentException(className + " is not a PacketExtensionProvider"));
                           }
                           break;
                        case 2:
                           this.sfProviders.add(new StreamFeatureProviderInfo(elementName, namespace, (ExtensionElementProvider)provider.newInstance()));
                           break;
                        default:
                           LOGGER.warning("Unknown provider type: " + typeName);
                        }
                     } catch (ClassNotFoundException var23) {
                        LOGGER.log(Level.SEVERE, "Could not find provider class", var23);
                        this.exceptions.add(var23);
                     } catch (InstantiationException var24) {
                        LOGGER.log(Level.SEVERE, "Could not instanciate " + className, var24);
                        this.exceptions.add(var24);
                     }
                  }
               } catch (IllegalArgumentException var25) {
                  LOGGER.log(Level.SEVERE, "Invalid provider type found [" + typeName + "] when expecting iqProvider or extensionProvider", var25);
                  this.exceptions.add(var25);
               }
            }

            eventType = parser.next();
         } while(eventType != 1);
      } catch (Exception var26) {
         LOGGER.log(Level.SEVERE, "Unknown error occurred while parsing provider file", var26);
         this.exceptions.add(var26);
      } finally {
         try {
            providerStream.close();
         } catch (Exception var22) {
         }

      }

   }

   public Collection<IQProviderInfo> getIQProviderInfo() {
      return this.iqProviders;
   }

   public Collection<ExtensionProviderInfo> getExtensionProviderInfo() {
      return this.extProviders;
   }

   public Collection<StreamFeatureProviderInfo> getStreamFeatureProviderInfo() {
      return this.sfProviders;
   }

   public List<Exception> getLoadingExceptions() {
      return Collections.unmodifiableList(this.exceptions);
   }
}
