package com.l7tech.gateway.common.admin;

import com.l7tech.gateway.common.export.ExternalReferenceFactory;
import com.l7tech.gateway.common.security.rbac.MethodStereotype;
import com.l7tech.gateway.common.security.rbac.Secured;
import com.l7tech.objectmodel.ConstraintViolationException;
import com.l7tech.objectmodel.DeleteException;
import com.l7tech.objectmodel.EntityType;
import com.l7tech.objectmodel.FindException;
import com.l7tech.objectmodel.Goid;
import com.l7tech.objectmodel.SaveException;
import com.l7tech.objectmodel.UpdateException;
import com.l7tech.policy.Policy;
import com.l7tech.policy.PolicyAlias;
import com.l7tech.policy.PolicyCheckpointState;
import com.l7tech.policy.PolicyDeletionForbiddenException;
import com.l7tech.policy.PolicyHeader;
import com.l7tech.policy.PolicyType;
import com.l7tech.policy.PolicyVersion;
import com.l7tech.policy.assertion.PolicyAssertionException;
import com.l7tech.util.DeserializeSafe;
import com.l7tech.util.Pair;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
@Secured(types = EntityType.POLICY)
@Administrative
@DeserializeSafe
public interface PolicyAdmin extends AliasAdmin<PolicyAlias> {
   String ROLE_NAME_TYPE_SUFFIX = "Policy";
   String ROLE_NAME_PATTERN = "Manage {0} Policy (#{1})";

   @Secured(stereotype = MethodStereotype.FIND_ENTITY)
   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   Policy findPolicyByPrimaryKey(Goid var1) throws FindException;

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

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

   @Secured(stereotype = MethodStereotype.FIND_ENTITIES)
   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   @NotNull
   List<Policy> findPoliciesByGuids(@NotNull List<String> var1) throws FindException;

   @Secured(stereotype = MethodStereotype.FIND_ENTITIES)
   @Transactional(readOnly = true)
   @NotNull
   Collection<Policy> findPoliciesByTypeTagAndSubTag(@NotNull PolicyType var1, @Nullable String var2, @Nullable String var3) throws FindException;

   @Secured(stereotype = MethodStereotype.FIND_HEADERS)
   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   Collection<PolicyHeader> findPolicyHeadersByType(PolicyType var1) throws FindException;

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.FIND_HEADERS)
   @Administrative(licensed = false)
   Collection<PolicyHeader> findPolicyHeadersWithTypes(EnumSet<PolicyType> var1) throws FindException;

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.FIND_HEADERS)
   @Administrative(licensed = false)
   Collection<PolicyHeader> findPolicyHeadersWithTypes(EnumSet<PolicyType> var1, boolean var2) throws FindException;

   @Secured(stereotype = MethodStereotype.DELETE_BY_ID)
   void deletePolicy(Goid var1) throws PolicyDeletionForbiddenException, DeleteException, FindException, ConstraintViolationException;

   @Secured(stereotype = MethodStereotype.SAVE_OR_UPDATE)
   Pair<Goid, String> savePolicy(Policy var1) throws PolicyAssertionException, SaveException;

   @Secured(stereotype = MethodStereotype.SAVE_OR_UPDATE)
   Goid saveAlias(PolicyAlias var1) throws SaveException;

   @Secured(stereotype = MethodStereotype.SAVE_OR_UPDATE, relevantArg = 0)
   PolicyCheckpointState savePolicy(Policy var1, boolean var2) throws PolicyAssertionException, SaveException;

   @Secured(stereotype = MethodStereotype.SAVE_OR_UPDATE, relevantArg = 0)
   PolicyAdmin.SavePolicyWithFragmentsResult savePolicy(Policy var1, boolean var2, HashMap<String, Policy> var3) throws PolicyAssertionException, SaveException;

   @Secured(stereotype = MethodStereotype.FIND_ENTITIES)
   Set<Policy> findUsages(Goid var1) throws FindException;

   @Secured(stereotype = MethodStereotype.GET_PROPERTY_BY_ID, relevantArg = 0)
   @Transactional(readOnly = true)
   PolicyVersion findPolicyVersionByPrimaryKey(Goid var1, Goid var2) throws FindException;

   @Secured(stereotype = MethodStereotype.GET_PROPERTY_BY_ID, relevantArg = 0)
   @Transactional(readOnly = true)
   List<PolicyVersion> findPolicyVersionHeadersByPolicy(Goid var1) throws FindException;

   @Secured(stereotype = MethodStereotype.SET_PROPERTY_BY_ID, relevantArg = 0)
   void setPolicyVersionComment(Goid var1, Goid var2, String var3) throws FindException, UpdateException;

   @Secured(stereotype = MethodStereotype.SET_PROPERTY_BY_ID, relevantArg = 0)
   void setActivePolicyVersion(Goid var1, Goid var2) throws FindException, UpdateException;

   @Secured(stereotype = MethodStereotype.GET_PROPERTY_BY_ID, relevantArg = 0)
   PolicyVersion findActivePolicyVersionForPolicy(Goid var1) throws FindException;

   @Secured(stereotype = MethodStereotype.GET_PROPERTY_BY_ID, relevantArg = 0)
   PolicyVersion findPolicyVersionForPolicy(Goid var1, long var2) throws FindException;

   @Secured(stereotype = MethodStereotype.SET_PROPERTY_BY_ID, relevantArg = 0)
   void clearActivePolicyVersion(Goid var1) throws FindException, UpdateException;

   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   @Transactional(readOnly = true)
   String getDefaultPolicyXml(PolicyType var1, String var2);

   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   @Transactional(readOnly = true)
   @NotNull
   Collection<PolicyAdmin.PolicyTagInfo> getPolicyTags(@NotNull PolicyType var1);

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   long getXmlMaxBytes();

   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   Set<ExternalReferenceFactory> findAllExternalReferenceFactories();

   @Secured(stereotype = MethodStereotype.GET_PROPERTY_BY_ID, relevantArg = 0)
   @Transactional(readOnly = true)
   PolicyVersion findLatestRevisionForPolicy(Goid var1);

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

   final class PolicyTagInfo implements Serializable {
      private static final long serialVersionUID = 4436438769393913753L;
      @NotNull
      public final String policyTag;
      @Nullable
      public final String defaultPolicyXml;
      @NotNull
      public final Set<String> policySubTags;
      private static final String[] a;

      public PolicyTagInfo(@NotNull String var1, @Nullable String var2, @Nullable Set<String> var3) {
         this.policyTag = var1;
         this.defaultPolicyXml = var2;
         this.policySubTags = var3 == null ? Collections.emptySet() : var3;
      }

      static {
         String[] var5 = new String[4];
         int var3 = 0;
         String var2 = "\r?,9\u0007J\tA9.9\u0010\rHP1";
         int var4 = "\r?,9\u0007J\tA9.9\u0010\rHP1".length();
         char var1 = 6;
         int var7 = -1;

         label24:
         while (true) {
            byte var10000 = 90;
            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 = "A*<l\fP{G&9l\u0007\u0006{G20:O\u0004`O(>-O\u0006kO,?l0\bcK&(\u0002\u0004\nfLa\u0001,\f\u000el[\u00110$)\tiM>c766\r\u0002aVe7,\u0012GOl*%\r\u0015\u000bc\u0002501\u0001\njV #cGB|\u0005e>%@B|\f`\"c\r\u0012|Ve?,\u0014GmGe?6\f\u000b";
                     var4 = "A*<l\fP{G&9l\u0007\u0006{G20:O\u0004`O(>-O\u0006kO,?l0\bcK&(\u0002\u0004\nfLa\u0001,\f\u000el[\u00110$)\tiM>c766\r\u0002aVe7,\u0012GOl*%\r\u0015\u000bc\u0002501\u0001\njV #cGB|\u0005e>%@B|\f`\"c\r\u0012|Ve?,\u0014GmGe?6\f\u000b"
                        .length();
                     var1 = '9';
                     var7 = -1;
               }

               var10000 = 73;
               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] ^ 70);
         }

         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 -> 107;
               case 1 -> 12;
               case 2 -> 24;
               case 3 -> 10;
               case 4 -> 41;
               case 5 -> 46;
               default -> 70;
            });
         }

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

   class SavePolicyWithFragmentsResult implements Serializable {
      public PolicyCheckpointState policyCheckpointState;
      public Map<String, String> fragmentNameGuidMap;
      static final long serialVersionUID = 4921745280917580631L;

      public SavePolicyWithFragmentsResult(PolicyCheckpointState var1, Map<String, String> var2) {
         this.policyCheckpointState = var1;
         this.fragmentNameGuidMap = var2;
      }
   }
}
