package com.l7tech.gateway.common.service;

import com.l7tech.gateway.common.AsyncAdminMethods;
import com.l7tech.gateway.common.admin.Administrative;
import com.l7tech.gateway.common.admin.AliasAdmin;
import com.l7tech.gateway.common.security.rbac.MethodStereotype;
import com.l7tech.gateway.common.security.rbac.Secured;
import com.l7tech.objectmodel.DeleteException;
import com.l7tech.objectmodel.EntityHeader;
import com.l7tech.objectmodel.EntityType;
import com.l7tech.objectmodel.FindException;
import com.l7tech.objectmodel.Goid;
import com.l7tech.objectmodel.PersistentEntity;
import com.l7tech.objectmodel.SaveException;
import com.l7tech.objectmodel.UpdateException;
import com.l7tech.objectmodel.VersionException;
import com.l7tech.policy.Policy;
import com.l7tech.policy.PolicyValidatorResult;
import com.l7tech.policy.assertion.PolicyAssertionException;
import com.l7tech.policy.validator.PolicyValidationContext;
import com.l7tech.uddi.UDDINamedEntity;
import com.l7tech.uddi.UDDIRegistryInfo;
import com.l7tech.uddi.WsdlPortInfo;
import com.l7tech.util.CollectionUpdate;
import com.l7tech.util.DeserializeSafe;
import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
@Secured(types = EntityType.SERVICE)
@Administrative
@DeserializeSafe
public interface ServiceAdmin extends AsyncAdminMethods, AliasAdmin<PublishedServiceAlias> {
   String ROLE_NAME_TYPE_SUFFIX = "Service";
   String ROLE_NAME_PATTERN = "Manage {0} Service (#{1})";

   @Secured(stereotype = MethodStereotype.FIND_HEADERS)
   @Transactional(readOnly = true)
   @Administrative(licensed = false, background = true)
   ServiceHeader[] findAllPublishedServices() throws FindException;

   @Secured(stereotype = MethodStereotype.FIND_HEADERS)
   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   ServiceHeader[] findAllPublishedServices(boolean var1) throws FindException;

   @Secured(stereotype = MethodStereotype.FIND_ENTITY)
   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   PublishedService findServiceByID(String var1) throws FindException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   String resolveWsdlTarget(String var1) throws IOException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   String resolveUrlTarget(String var1, String var2) throws IOException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   String resolveUrlTarget(String var1, ServiceAdmin.DownloadDocumentType var2, String var3) throws IOException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   AsyncAdminMethods.JobId<String> resolveUrlTargetAsync(String var1, String var2);

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   String resolveUrlTarget(String var1, ServiceAdmin.DownloadDocumentType var2) throws IOException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   AsyncAdminMethods.JobId<String> resolveUrlTargetAsync(String var1, ServiceAdmin.DownloadDocumentType var2);

   @Transactional(readOnly = true)
   @Secured(types = EntityType.SERVICE, stereotype = MethodStereotype.GET_PROPERTY_BY_ID)
   @Administrative(licensed = false)
   Collection<ServiceDocument> findServiceDocumentsByServiceID(String var1) throws FindException;

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.FIND_HEADERS)
   @Administrative(licensed = false)
   ServiceHeader[] findAllPublishedServicesByOffset(int var1, int var2) throws FindException;

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.FIND_HEADERS)
   @Administrative(licensed = false, background = true)
   CollectionUpdate<ServiceHeader> getPublishedServicesUpdate(int var1) throws FindException;

   @Secured(stereotype = MethodStereotype.SAVE_OR_UPDATE)
   Goid savePublishedService(PublishedService var1) throws UpdateException, SaveException, VersionException, PolicyAssertionException;

   @Secured(stereotype = MethodStereotype.SAVE_OR_UPDATE, relevantArg = 0)
   Goid savePublishedServiceWithDocuments(PublishedService var1, Collection<ServiceDocument> var2) throws UpdateException, SaveException, VersionException, PolicyAssertionException;

   @Secured(stereotype = MethodStereotype.SET_PROPERTY_BY_UNIQUE_ATTRIBUTE)
   void setTracingEnabled(Goid var1, boolean var2) throws UpdateException;

   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   AsyncAdminMethods.JobId<PolicyValidatorResult> validatePolicy(String var1, PolicyValidationContext var2);

   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   AsyncAdminMethods.JobId<PolicyValidatorResult> validatePolicy(String var1, PolicyValidationContext var2, HashMap<String, Policy> var3);

   @Transactional(readOnly = true)
   @Secured(types = EntityType.UDDI_REGISTRY, stereotype = MethodStereotype.GET_PROPERTY_BY_ID, relevantArg = 0)
   AsyncAdminMethods.JobId<WsdlPortInfo[]> findWsdlInfosFromUDDIRegistry(Goid var1, String var2, boolean var3, boolean var4);

   @Transactional(readOnly = true)
   @Secured(types = EntityType.UDDI_REGISTRY, stereotype = MethodStereotype.GET_PROPERTY_BY_ID, relevantArg = 0)
   AsyncAdminMethods.JobId<WsdlPortInfo[]> findWsdlInfosForSingleBusinessService(Goid var1, String var2, boolean var3) throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.UDDI_REGISTRY, stereotype = MethodStereotype.GET_PROPERTY_BY_ID, relevantArg = 0)
   AsyncAdminMethods.JobId<UDDINamedEntity[]> findBusinessesFromUDDIRegistry(Goid var1, String var2, boolean var3);

   @Transactional(readOnly = true)
   @Secured(types = EntityType.UDDI_REGISTRY, stereotype = MethodStereotype.GET_PROPERTY_BY_ID, relevantArg = 0)
   UDDINamedEntity[] findPoliciesFromUDDIRegistry(Goid var1, String var2) throws FindException;

   @Secured(types = EntityType.SAMPLE_MESSAGE, stereotype = MethodStereotype.FIND_ENTITY)
   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   SampleMessage findSampleMessageById(Goid var1) throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.SAMPLE_MESSAGE, stereotype = MethodStereotype.FIND_HEADERS)
   @Administrative(licensed = false)
   EntityHeader[] findSampleMessageHeaders(Goid var1, String var2) throws FindException;

   @Secured(types = EntityType.SAMPLE_MESSAGE, stereotype = MethodStereotype.SAVE_OR_UPDATE)
   Goid saveSampleMessage(SampleMessage var1) throws SaveException;

   @Secured(types = EntityType.SAMPLE_MESSAGE, stereotype = MethodStereotype.DELETE_ENTITY)
   void deleteSampleMessage(SampleMessage var1) throws DeleteException;

   @Secured(stereotype = MethodStereotype.DELETE_BY_ID)
   void deletePublishedService(String var1) throws DeleteException;

   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   String getPolicyURL(String var1, boolean var2) throws FindException;

   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   String getConsumptionURL(String var1) throws FindException;

   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   Collection<UDDIRegistryInfo> getUDDIRegistryInfo();

   @Transactional(readOnly = true)
   @Secured(types = EntityType.SERVICE_TEMPLATE, stereotype = MethodStereotype.FIND_ENTITIES)
   Set<ServiceTemplate> findAllTemplates();

   @Secured(types = EntityType.SERVICE_TEMPLATE, stereotype = MethodStereotype.FIND_ENTITY)
   ServiceTemplate createSecurityTokenServiceTemplate(String var1);

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.GET_PROPERTY_OF_ENTITY, relevantArg = 0)
   ServiceAdmin.ResolutionReport generateResolutionReport(PublishedService var1, Collection<ServiceDocument> var2) throws FindException;

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.SAVE_OR_UPDATE, relevantArg = 0)
   ServiceAdmin.ResolutionReport generateResolutionReportForNewService(PublishedService var1, Collection<ServiceDocument> var2) throws FindException;

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.FIND_ENTITY, types = EntityType.SERVICE)
   PublishedService findByAlias(Goid var1) throws FindException;

   class ConflictInfo implements Serializable, Comparable<ServiceAdmin.ConflictInfo> {
      private final Goid serviceGoid;
      private final String serviceName;
      private final String serviceDisplayName;
      private final String soapAction;
      private final String soapPayloadNamespace;
      private final String path;
      static final long serialVersionUID = 1702398958804531030L;

      public ConflictInfo(String var1, String var2, String var3, Goid var4, String var5, String var6) {
         this.path = var1;
         this.serviceDisplayName = var2;
         this.serviceName = var3;
         this.serviceGoid = var4;
         this.soapAction = var5;
         this.soapPayloadNamespace = var6;
      }

      public String getPath() {
         return this.path == null ? "" : this.path;
      }

      public String getServiceDisplayName() {
         return this.serviceDisplayName;
      }

      public String getServiceName() {
         return this.serviceName;
      }

      public Goid getServiceGoid() {
         return this.serviceGoid;
      }

      public String getSoapAction() {
         return this.soapAction == null ? "" : this.soapAction;
      }

      public String getSoapPayloadNamespace() {
         return this.soapPayloadNamespace == null ? "" : this.soapPayloadNamespace;
      }

      private int compareMaybeNull(String var1, String var2) {
         if (var1 != null && var2 != null) {
            return var1.compareTo(var2);
         } else if (var1 != null) {
            return 1;
         } else {
            return var2 != null ? -1 : 0;
         }
      }

      public int compareTo(ServiceAdmin.ConflictInfo var1) {
         int var2 = this.serviceGoid.compareTo(var1.getServiceGoid());
         if (var2 == 0) {
            var2 = this.compareMaybeNull(this.path, var1.getPath());
         }

         if (var2 == 0) {
            var2 = this.compareMaybeNull(this.soapPayloadNamespace, var1.getSoapPayloadNamespace());
         }

         if (var2 == 0) {
            var2 = this.compareMaybeNull(this.soapAction, var1.getSoapAction());
         }

         return var2;
      }

      @Override
      public boolean equals(Object var1) {
         if (this == var1) {
            return true;
         }

         if (var1 != null && this.getClass() == var1.getClass()) {
            ServiceAdmin.ConflictInfo var2 = (ServiceAdmin.ConflictInfo)var1;
            if (!Goid.equals(this.serviceGoid, var2.serviceGoid)) {
               return false;
            }

            if (this.path != null ? this.path.equals(var2.path) : var2.path == null) {
               if (this.serviceDisplayName != null ? this.serviceDisplayName.equals(var2.serviceDisplayName) : var2.serviceDisplayName == null) {
                  if (this.serviceName != null ? this.serviceName.equals(var2.serviceName) : var2.serviceName == null) {
                     if (this.soapAction != null ? this.soapAction.equals(var2.soapAction) : var2.soapAction == null) {
                        return this.soapPayloadNamespace != null
                           ? this.soapPayloadNamespace.equals(var2.soapPayloadNamespace)
                           : var2.soapPayloadNamespace == null;
                     } else {
                        return false;
                     }
                  } else {
                     return false;
                  }
               } else {
                  return false;
               }
            } else {
               return false;
            }
         } else {
            return false;
         }
      }

      @Override
      public int hashCode() {
         int var1 = this.serviceGoid != null ? this.serviceGoid.hashCode() : 0;
         var1 = 31 * var1 + (this.serviceName != null ? this.serviceName.hashCode() : 0);
         var1 = 31 * var1 + (this.serviceDisplayName != null ? this.serviceDisplayName.hashCode() : 0);
         var1 = 31 * var1 + (this.soapAction != null ? this.soapAction.hashCode() : 0);
         var1 = 31 * var1 + (this.soapPayloadNamespace != null ? this.soapPayloadNamespace.hashCode() : 0);
         return 31 * var1 + (this.path != null ? this.path.hashCode() : 0);
      }
   }

   enum DownloadDocumentType {
      WSDL,
      SCHEMA,
      XSL,
      UNKNOWN,
      MOD_ASS;

      // $VF: Failed to inline enum fields
      // Please report this to the Vineflower issue tracker, at https://github.com/Vineflower/vineflower/issues with a copy of the class file (if you have the rights to distribute it!)
      static {
         String[] var0 = new String[5];
         int var4 = 0;
         String var3 = "T\u0003\tg#\u0004G\u0007L\u0002\u0006v-\u0000Z\u0003Y\u001e\u000e";
         int var5 = "T\u0003\tg#\u0004G\u0007L\u0002\u0006v-\u0000Z\u0003Y\u001e\u000e".length();
         char var2 = 7;
         int var7 = -1;

         label25:
         while (true) {
            byte var10000 = 63;
            String var10001 = var3.substring(++var7, var7 + var2);
            byte var10002 = -1;

            while (true) {
               String var8 = a(var10000, a(var10001));
               switch (var10002) {
                  case 0:
                     var0[var4++] = var8;
                     if ((var7 += var2) >= var5) {
                        WSDL = new ServiceAdmin.DownloadDocumentType();
                        SCHEMA = new ServiceAdmin.DownloadDocumentType();
                        XSL = new ServiceAdmin.DownloadDocumentType();
                        UNKNOWN = new ServiceAdmin.DownloadDocumentType();
                        MOD_ASS = new ServiceAdmin.DownloadDocumentType();
                        return;
                     }

                     var2 = var3.charAt(var7);
                     break;
                  default:
                     var0[var4++] = var8;
                     if ((var7 += var2) < var5) {
                        var2 = var3.charAt(var7);
                        continue label25;
                     }

                     var3 = "`(0S\u0006d8<Z\u0017$";
                     var5 = "`(0S\u0006d8<Z\u0017$".length();
                     var2 = 4;
                     var7 = -1;
               }

               var10000 = 9;
               var10001 = var3.substring(++var7, var7 + var2);
               var10002 = 0;
            }
         }
      }

      private static char[] a(String var0) {
         char[] var10000 = var0.toCharArray();
         if (var10000.length < 2) {
            var10000[0] = (char)(var10000[0] ^ 54);
         }

         return var10000;
      }

      private static String a(int var0, char[] var1) {
         int var10003 = var1.length;
         int var10002 = var0;
         char[] var10001 = var1;
         int var10000 = var10003;

         for (int var2 = 0; var10000 > var2; var2++) {
            var10001[var2] = (char)(var10001[var2] ^ var10002 ^ switch (var2 % 7) {
               case 0 -> 62;
               case 1 -> 114;
               case 2 -> 125;
               case 3 -> 22;
               case 4 -> 83;
               case 5 -> 108;
               default -> 54;
            });
         }

         return new String(var10001).intern();
      }
   }

   class ResolutionReport implements Serializable {
      private final boolean resolvesByPath;
      private final ServiceAdmin.ConflictInfo[] conflicts;
      static final long serialVersionUID = -6073138944492115609L;
      private static final String[] a;

      public ResolutionReport(boolean var1, ServiceAdmin.ConflictInfo[] var2) {
         this.resolvesByPath = var1;
         this.conflicts = var2;
      }

      public ServiceAdmin.ConflictInfo[] getConflicts() {
         return this.conflicts;
      }

      public boolean isResolvesByPath() {
         return this.resolvesByPath;
      }

      public boolean isSuccess() {
         return this.resolvesByPath && (this.conflicts == null || this.conflicts.length == 0);
      }

      @Override
      public String toString() {
         StringBuilder var1 = new StringBuilder();
         String[] var8 = a;
         var1.append(var8[3]);
         String var10001;
         if (this.resolvesByPath) {
            var10001 = var8[7];
         } else {
            var8 = a;
            var10001 = var8[4];
         }

         var1.append(var10001);
         if (this.conflicts != null && this.conflicts.length > 0) {
            var8 = a;
            var1.append(var8[0]);
            var1.append(var8[5]);
            List var2 = Arrays.asList(this.conflicts);
            Collections.sort(var2);
            Goid var3 = PersistentEntity.DEFAULT_GOID;

            for (ServiceAdmin.ConflictInfo var7 : this.conflicts) {
               if (!Goid.equals(var7.getServiceGoid(), var3)) {
                  var3 = var7.getServiceGoid();
                  var8 = a;
                  var1.append(var8[6]);
                  var1.append(var7.getServiceDisplayName());
               }

               var8 = a;
               var1.append(var8[2]).append(var7.getSoapPayloadNamespace());
               var1.append(var8[1]).append(var7.getSoapAction());
            }
         }

         return var1.toString();
      }

      static {
         String[] var5 = new String[8];
         int var3 = 0;
         String var2 = "\u000f\u000f\n)%Tb5w\u0007k?5\t\u000f%5!aP;?%\u0019W`fn-h\rv%`r(p\u000f%CAQnV<QU/!\u0002Kj\u0015Fj{g-w\u000bql{fam\rws|b$mR";
         int var4 = "\u000f\u000f\n)%Tb5w\u0007k?5\t\u000f%5!aP;?%\u0019W`fn-h\rv%`r(p\u000f%CAQnV<QU/!\u0002Kj\u0015Fj{g-w\u000bql{fam\rws|b$mR".length();
         char var1 = 2;
         int var7 = -1;

         label24:
         while (true) {
            byte var10000 = 45;
            String var10001 = var2.substring(++var7, var7 + var1);
            byte var10002 = -1;

            while (true) {
               String var8 = a(var10000, a(var10001));
               switch (var10002) {
                  case 0:
                     var5[var3++] = var8;
                     if ((var7 += var1) >= var4) {
                        a = var5;
                        return;
                     }

                     var1 = var2.charAt(var7);
                     break;
                  default:
                     var5[var3++] = var8;
                     if ((var7 += var1) < var4) {
                        var1 = var2.charAt(var7);
                        continue label24;
                     }

                     var2 = ">\u0014\u0004c\u0015]/]WA\nP\u0003mQW";
                     var4 = ">\u0014\u0004c\u0015]/]WA\nP\u0003mQW".length();
                     var1 = '\f';
                     var7 = -1;
               }

               var10000 = 28;
               var10001 = var2.substring(++var7, var7 + var1);
               var10002 = 0;
            }
         }
      }

      private static char[] a(String var0) {
         char[] var10000 = var0.toCharArray();
         if (var10000.length < 2) {
            var10000[0] = (char)(var10000[0] ^ 69);
         }

         return var10000;
      }

      private static String a(int var0, char[] var1) {
         int var10003 = var1.length;
         int var10002 = var0;
         char[] var10001 = var1;
         int var10000 = var10003;

         for (int var2 = 0; var10000 > var2; var2++) {
            var10001[var2] = (char)(var10001[var2] ^ var10002 ^ switch (var2 % 7) {
               case 0 -> 40;
               case 1 -> 40;
               case 2 -> 56;
               case 3 -> 44;
               case 4 -> 108;
               case 5 -> 51;
               default -> 69;
            });
         }

         return new String(var10001).intern();
      }
   }
}
