<%_ if (position === 'import') { _%>
import <%= packageName %>.security.SecurityUtils;
import <%= packageName %>.security.annotation.PermissionDefine;
import <%= packageName %>.domain.enumeration.ApiPermissionType;
    <%_ if (databaseTypeMongodb) { _%>
import <%= packageName %>.repository.AuthorityRepository;
    <%_ } _%>
import org.springframework.web.bind.annotation.*;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.<%= reactive ? 'reactive.result' : 'servlet.mvc' %>.condition.PatternsRequestCondition;
import org.springframework.web.<%= reactive ? 'reactive.result' : 'servlet.mvc' %>.method.RequestMappingInfo;
import org.springframework.web.<%= reactive ? 'reactive.result' : 'servlet.mvc' %>.method.annotation.RequestMappingHandlerMapping;
<%_ } _%>
<%_ if (position === 'importInterface') { _%>
import <%= packageName %>.domain.enumeration.ApiPermissionType;
    <%_ if (databaseTypeMongodb) { _%>
import <%= packageName %>.repository.AuthorityRepository;
    <%_ } _%>
import org.springframework.web.bind.annotation.*;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.<%= reactive ? 'reactive.result' : 'servlet.mvc' %>.method.annotation.RequestMappingHandlerMapping;
<%_ } _%>
<%_ if (position === 'extendsImport') { _%>
import org.springframework.web.<%= reactive ? 'reactive.result' : 'servlet.mvc' %>.method.annotation.RequestMappingHandlerMapping;
<%_ } _%>
<%_ if (position === 'methodInterface') { _%>
    /**
     * Get all the apiPermissions.
     *
     * @param type the ApiPermissionType.
     * @return the list of entities.
     */
    <%= reactive ? 'Flux' : 'List' %><ApiPermissionDTO> findAllByType(ApiPermissionType type);

    /**
     * regenerate ApiPermissions from Annotation
     */
    void regenerateApiPermissions();

    <%= reactive ? 'Flux' : 'List' %><ApiPermissionDTO> findAllApiPermissionsByCurrentUser();

<%_ } _%>
<%_ if (position === 'method') { _%>

    /**
     * Get all the apiPermissions.
     *
     * @param type the ApiPermissionType.
     * @return the list of entities.
     */
    <%_ if (databaseTypeSql && ormTool === 'hibernate') { _%>
    @Transactional(readOnly = true)
    <%_ } _%>
    public <%= reactive ? 'Flux' : 'List' %><ApiPermissionDTO> findAllByType(ApiPermissionType type) {
        LOG.debug("Request to get all ApiPermissions by type");
        <%_ if (!reactive) { _%>
        return apiPermissionMapper.toDto(apiPermissionRepository.findAllByType(type));
        <%_ } else { _%>
        return apiPermissionRepository.findAllByType(type).map(apiPermissionMapper::toDto);
        <%_ } _%>
    }
   <%_ if (ormTool === 'mybatis' && databaseTypeSql) { _%>

    /**
     * regenerate ApiPermissions from Annotation
     */
    @Transactional
    public void regenerateApiPermissions() {
        Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> m : map.entrySet()) {
            HandlerMethod method = m.getValue();
            PermissionDefine permissionDefineAnnotation = method.getMethodAnnotation(PermissionDefine.class);
            if (permissionDefineAnnotation != null) {
                // 处理group
                ApiPermission apiPermissionGroup = apiPermissionRepository.findOneByCode(permissionDefineAnnotation.groupCode())
                    .orElseGet(() -> {
                        ApiPermission permission = new ApiPermission()
                            .code(permissionDefineAnnotation.groupCode())
                            .name(permissionDefineAnnotation.groupName())
                            .type(ApiPermissionType.BUSINESS);
                        apiPermissionRepository.insert(permission);
                        return this.getById(permission.getId());
                    });
                // 处理实体
                ApiPermission apiPermissionEntity = apiPermissionRepository.findOneByCode(permissionDefineAnnotation.groupCode() + "_" +permissionDefineAnnotation.entityCode())
                    .orElseGet(() -> {
                        ApiPermission permission = new ApiPermission()
                            .code(permissionDefineAnnotation.groupCode() + "_" + permissionDefineAnnotation.entityCode())
                            .name(permissionDefineAnnotation.entityName())
                            .type(ApiPermissionType.ENTITY);
                        apiPermissionRepository.insert(permission);
                        return this.getById(permission.getId());
                    });
                this.saveOrUpdate(apiPermissionEntity.parent(apiPermissionGroup));
                // 处理permission
                // 获得相关的methodType

                ApiPermission apiPermission = apiPermissionRepository.findOneByCode(permissionDefineAnnotation.groupCode() + "_" + permissionDefineAnnotation.entityCode() + "_" + permissionDefineAnnotation.permissionCode())
                    .orElseGet(() -> {
                        ApiPermission permission = new ApiPermission()
                            .code(permissionDefineAnnotation.groupCode() + "_" + permissionDefineAnnotation.entityCode() + "_" + permissionDefineAnnotation.permissionCode())
                            .name(permissionDefineAnnotation.permissionName())
                            .parent(apiPermissionEntity)
                            .type(ApiPermissionType.API)
                            .status(permissionDefineAnnotation.state());
                        apiPermissionRepository.insert(permission);
                        return this.getById(permission.getId());
                    });

                GetMapping getMappingAnnotation = method.getMethodAnnotation(GetMapping.class);
                PostMapping postMappingAnnotation = method.getMethodAnnotation(PostMapping.class);
                DeleteMapping deleteMappingAnnotation = method.getMethodAnnotation(DeleteMapping.class);
                PutMapping putMappingAnnotation = method.getMethodAnnotation(PutMapping.class);
                RequestMapping requestMappingAnnotation = method.getMethodAnnotation(RequestMapping.class);
                StringBuilder methodType = new StringBuilder();
                if (getMappingAnnotation != null) {
                    methodType = new StringBuilder("GET");
                }
                if (postMappingAnnotation != null) {
                    methodType = new StringBuilder("POST");
                }
                if (deleteMappingAnnotation != null) {
                    methodType = new StringBuilder("DELETE");
                }
                if (putMappingAnnotation != null) {
                    methodType = new StringBuilder("PUT");
                }
                if (requestMappingAnnotation != null) {
                    if (requestMappingAnnotation.method().length > 0) {
                        RequestMethod[] methods = requestMappingAnnotation.method();
                        for (RequestMethod r : methods) {
                            if (methodType.indexOf(r.name()) == -1) {
                                methodType.append(",").append(r.name());
                            }
                        }
                        if (methodType.charAt(0) == ',') {
                            methodType.deleteCharAt(0);
                        }
                    }
                }
                // url
                PatternsRequestCondition patternsCondition = m.getKey().getPatternsCondition();
                String url = patternsCondition.toString();
                apiPermission.method(methodType.toString())
                             .url(url)
                             .status(permissionDefineAnnotation.state());
                this.saveOrUpdate(apiPermission.parent(apiPermissionEntity));
            }
        }
    }
    <%_ } else { _%>

    /**
     * regenerate ApiPermissions from Annotation
     */
    public void regenerateApiPermissions() {
        Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> m : map.entrySet()) {
            HandlerMethod method = m.getValue();
            PermissionDefine permissionDefineAnnotation = method.getMethodAnnotation(PermissionDefine.class);
            if (permissionDefineAnnotation != null) {
                // 处理group
                ApiPermission apiPermissionGroup = apiPermissionRepository.findOneByCode(permissionDefineAnnotation.groupCode())
                    <% if (!reactive) { %>.orElseGet(() -> <% } else { %>.switchIfEmpty(<% } %>
                        apiPermissionRepository.save(
                        new ApiPermission()
                            .code(permissionDefineAnnotation.groupCode())
                            .name(permissionDefineAnnotation.groupName())
                            .type(ApiPermissionType.BUSINESS)))<% if (reactive) { %>.block()<% } %>;
                // 处理实体
                ApiPermission apiPermissionEntity = apiPermissionRepository.findOneByCode(permissionDefineAnnotation.groupCode() + "_" +permissionDefineAnnotation.entityCode())
                    <% if (!reactive) { %>.orElseGet(() -> <% } else { %>.switchIfEmpty(<% } %>
                        apiPermissionRepository.save(
                        new ApiPermission()
                            .code(permissionDefineAnnotation.groupCode() + "_" + permissionDefineAnnotation.entityCode())
                            .name(permissionDefineAnnotation.entityName())
                            .type(ApiPermissionType.ENTITY)))<% if (reactive) { %>.block()<% } %>;
                apiPermissionRepository.save(apiPermissionEntity.parent(apiPermissionGroup));
                // 处理permission
                // 获得相关的methodType

                ApiPermission apiPermission = apiPermissionRepository.findOneByCode(permissionDefineAnnotation.groupCode() + "_" + permissionDefineAnnotation.entityCode() + "_" + permissionDefineAnnotation.permissionCode())
                    <% if (!reactive) { %>.orElseGet(() -> <% } else { %>.switchIfEmpty(<% } %>
                        apiPermissionRepository.save(
                        new ApiPermission()
                            .code(permissionDefineAnnotation.groupCode() + "_" + permissionDefineAnnotation.entityCode() + "_" + permissionDefineAnnotation.permissionCode())
                            .name(permissionDefineAnnotation.permissionName())
                            .parent(apiPermissionEntity)
                            .type(ApiPermissionType.API)
                            .status(permissionDefineAnnotation.state())))<% if (reactive) { %>.block()<% } %>;

                GetMapping getMappingAnnotation = method.getMethodAnnotation(GetMapping.class);
                PostMapping postMappingAnnotation = method.getMethodAnnotation(PostMapping.class);
                DeleteMapping deleteMappingAnnotation = method.getMethodAnnotation(DeleteMapping.class);
                PutMapping putMappingAnnotation = method.getMethodAnnotation(PutMapping.class);
                RequestMapping requestMappingAnnotation = method.getMethodAnnotation(RequestMapping.class);
                StringBuilder methodType = new StringBuilder();
                if (getMappingAnnotation != null) {
                    methodType = new StringBuilder("GET");
                }
                if (postMappingAnnotation != null) {
                    methodType = new StringBuilder("POST");
                }
                if (deleteMappingAnnotation != null) {
                    methodType = new StringBuilder("DELETE");
                }
                if (putMappingAnnotation != null) {
                    methodType = new StringBuilder("PUT");
                }
                if (requestMappingAnnotation != null && requestMappingAnnotation.method() != null) {
                    if (requestMappingAnnotation.method().length > 0) {
                        RequestMethod[] methods = requestMappingAnnotation.method();
                        for (RequestMethod r : methods) {
                            if (methodType.indexOf(r.name()) == -1) {
                                methodType.append(",").append(r.name());
                            }
                        }
                        if (methodType.charAt(0) == ',') {
                            methodType.deleteCharAt(0);
                        }
                    }
                }
                // url
                PatternsRequestCondition patternsCondition = m.getKey().getPatternsCondition();
                String url = patternsCondition.toString();
                apiPermission.method(methodType.toString())
                             .url(url)
                             .status(permissionDefineAnnotation.state());
                apiPermissionRepository.save(apiPermission.parent(apiPermissionEntity));
            }
        }
    }
    <%_ } _%>

    <%_ if (databaseTypeSql && ormTool === 'hibernate') { _%>
    @Transactional(readOnly = true)
    <%_ } _%>
    public <%= reactive ? 'Flux' : 'List' %><ApiPermissionDTO> findAllApiPermissionsByCurrentUser() {
        <% if (!reactive) { %>if (SecurityUtils.isAuthenticated()) {<% } else { %>if (Boolean.TRUE.equals(SecurityUtils.isAuthenticated().block())) {<% } %>
            <%_ if (databaseTypeSql) { _%>
                <%_ if (reactive) { _%>
            return apiPermissionRepository.findAllApiPermissionsByCurrentUser().map(apiPermissionMapper::toDto);
                <%_ } else { _%>
            return apiPermissionMapper.toDto(apiPermissionRepository.findAllApiPermissionsByCurrentUser(<%- ormTool === 'mybatis' ? `SecurityUtils.getCurrentUserId().orElseThrow()` : '' %>));
                <%_ } _%>
            <%_ } else { _%>
            return apiPermissionMapper.toDto(
                apiPermissionRepository.findAllByAuthoritiesIn(
                    authorityRepository.findByUsersId(SecurityUtils.getCurrentUserId().orElseThrow())));
            <%_ } _%>
        } else {
            <% if (!reactive) { %>return new ArrayList<>();<% } else { %>return Flux.empty();<% } %>
        }
    }
<%_ } _%>
