package com.l7tech.gateway.common.security.rbac;

import com.l7tech.gateway.common.admin.Administrative;
import com.l7tech.identity.Group;
import com.l7tech.identity.Identity;
import com.l7tech.identity.User;
import com.l7tech.objectmodel.DeleteException;
import com.l7tech.objectmodel.Entity;
import com.l7tech.objectmodel.EntityHeader;
import com.l7tech.objectmodel.EntityHeaderSet;
import com.l7tech.objectmodel.EntityType;
import com.l7tech.objectmodel.FindException;
import com.l7tech.objectmodel.Goid;
import com.l7tech.objectmodel.SaveException;
import com.l7tech.objectmodel.SecurityZone;
import com.l7tech.objectmodel.UpdateException;
import com.l7tech.policy.AssertionAccess;
import com.l7tech.util.Pair;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
@Administrative
@Secured(types = EntityType.RBAC_ROLE)
public interface RbacAdmin {
   String ROLE_NAME_PREFIX = "Manage";
   String ROLE_NAME_PREFIX_READ = "View";
   String ROLE_NAME_OID_SUFFIX = " (#{1})";
   String RENAME_REGEX_PATTERN = "(?<=^\\w'{'1,128'}' ).*?(?= {0} \\(#[\\d[\\d, ]|[A-Za-z0-9]]*\\)$)";
   String ZONE_ROLE_NAME_TYPE_SUFFIX = "Zone";

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.FIND_ENTITIES)
   Collection<Role> findAllRoles() throws FindException;

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.FIND_HEADERS)
   Collection<EntityHeader> findAllRoleHeaders() throws FindException;

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.FIND_ENTITY)
   Role findRoleByPrimaryKey(Goid var1) throws FindException;

   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   @NotNull
   Collection<Permission> findCurrentUserPermissions() throws FindException;

   @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
   @Administrative(licensed = false)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   @NotNull
   Map<String, EntityProtectionInfo> findProtectedEntities() throws FindException;

   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   @NotNull
   Pair<Collection<Permission>, Map<String, EntityProtectionInfo>> findCurrentUserPermissionsAndProtectedEntities() throws FindException;

   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   Collection<Role> findRolesForUser(User var1) throws FindException;

   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   Role findDefaultRoleForIdentityProvider(Goid var1) throws FindException;

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.FIND_ENTITIES)
   @NotNull
   Collection<Role> findRolesForGroup(@NotNull Group var1) throws FindException;

   @Secured(stereotype = MethodStereotype.SAVE_OR_UPDATE)
   Goid saveRole(@NotNull Role var1) throws SaveException;

   @Secured(stereotype = MethodStereotype.SAVE_OR_UPDATE)
   Goid saveRole(@NotNull Role var1, @NotNull Collection<Pair<RoleAssignment, Identity>> var2, @NotNull Collection<RoleAssignment> var3) throws SaveException;

   @Secured(stereotype = MethodStereotype.DELETE_ENTITY)
   void deleteRole(Role var1) throws DeleteException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.ANY, stereotype = MethodStereotype.FIND_HEADERS)
   EntityHeaderSet<EntityHeader> findEntities(EntityType var1) throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.SECURITY_ZONE, stereotype = MethodStereotype.FIND_ENTITIES)
   Collection<SecurityZone> findAllSecurityZones() throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.SECURITY_ZONE, stereotype = MethodStereotype.FIND_ENTITY)
   SecurityZone findSecurityZoneByPrimaryKey(Goid var1) throws FindException;

   @Secured(types = EntityType.SECURITY_ZONE, stereotype = MethodStereotype.SAVE_OR_UPDATE)
   Goid saveSecurityZone(SecurityZone var1) throws SaveException;

   @Secured(types = EntityType.SECURITY_ZONE, stereotype = MethodStereotype.DELETE_ENTITY)
   void deleteSecurityZone(SecurityZone var1) throws DeleteException;

   @Secured(stereotype = MethodStereotype.FIND_ENTITIES)
   Collection<EntityHeader> findEntitiesByTypeAndSecurityZoneGoid(@NotNull EntityType var1, Goid var2) throws FindException;

   @Secured(customInterceptor = "com.l7tech.server.security.rbac.SecurityZoneRbacInterceptor")
   void setSecurityZoneForEntities(Goid var1, @NotNull EntityType var2, @NotNull Collection<Serializable> var3) throws UpdateException;

   @Secured(customInterceptor = "com.l7tech.server.security.rbac.SecurityZoneRbacInterceptor")
   void setSecurityZoneForEntities(Goid var1, @NotNull Map<EntityType, Collection<Serializable>> var2) throws UpdateException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.ASSERTION_ACCESS, stereotype = MethodStereotype.FIND_ENTITIES)
   Collection<AssertionAccess> findAccessibleAssertions() throws FindException;

   @Secured(types = EntityType.ASSERTION_ACCESS, stereotype = MethodStereotype.SAVE_OR_UPDATE)
   Goid saveAssertionAccess(AssertionAccess var1) throws UpdateException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.ANY, stereotype = MethodStereotype.FIND_HEADERS)
   EntityHeader findHeader(EntityType var1, Serializable var2) throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.ANY, stereotype = MethodStereotype.FIND_ENTITY)
   Entity find(@NotNull EntityHeader var1) throws FindException;
}
