<beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security.xsd">

    <!-- JWT -->
    <global-method-security pre-post-annotations="enabled"/>

    <!-- Skip login, Sign-up resources -->
    <http pattern="/**/login" auto-config="true" use-expressions="true">
        <intercept-url pattern="/**/login" access="permitAll"/>
        <headers>
            <xss-protection disabled="true"/>
            <header ref="cspHeaderWriter"/>
        </headers>
        <csrf disabled="true"/>
    </http>

    <http pattern="/**/validateLogin" auto-config="true" use-expressions="true">
        <intercept-url pattern="/**/validateLogin" access="permitAll"/>
        <headers>
            <xss-protection disabled="true"/>
            <header ref="cspHeaderWriter"/>
        </headers>
        <csrf disabled="true"/>
    </http>
    <http  request-matcher-ref="registerMatcher" auto-config="true" use-expressions="true">
        <intercept-url pattern="/register/**" access="permitAll"/>
        <headers>
            <xss-protection disabled="true"/>
            <header ref="cspHeaderWriter"/>
        </headers>
        <csrf disabled="true"/>
    </http>
    <http pattern="/profile/**/forgotUserName" auto-config="true" use-expressions="true">
        <intercept-url pattern="/profile/**/forgotUserName" access="permitAll"/>
        <headers>
            <xss-protection disabled="true"/>
            <header ref="cspHeaderWriter"/>
        </headers>
        <csrf disabled="true"/>
    </http>
    <http pattern="/profile/**/forgotPassword" auto-config="true" use-expressions="true">
        <intercept-url pattern="/profile/**/forgotPassword" access="permitAll"/>
        <headers>
            <xss-protection disabled="true"/>
            <header ref="cspHeaderWriter"/>
        </headers>
        <csrf disabled="true"/>
    </http>
    <http pattern="/profile/**/setNewPassword" auto-config="true" use-expressions="true">
        <intercept-url pattern="/profile/**/setNewPassword" access="permitAll"/>
        <headers>
            <xss-protection disabled="true"/>
            <header ref="cspHeaderWriter"/>
        </headers>
        <csrf disabled="true"/>
    </http>
    <http pattern="/**/checkForUpdates" auto-config="true" use-expressions="true">
        <intercept-url pattern="/**/checkForUpdates" access="permitAll"/>
        <headers>
            <xss-protection disabled="true"/>
            <header ref="cspHeaderWriter"/>
        </headers>
        <csrf disabled="true"/>
    </http>

    <http pattern="/app/status" auto-config="true" use-expressions="true">
        <intercept-url pattern="/app/status" access="permitAll"/>
        <headers>
            <xss-protection disabled="true"/>
            <header ref="cspHeaderWriter"/>
        </headers>
        <csrf disabled="true"/>
    </http>

    <!-- Apply Security to all other resources -->
    <http request-matcher-ref="secureMatcher" auto-config="true" use-expressions="true" entry-point-ref="jwtAuthEntryPoint" create-session="stateless">
        <intercept-url pattern="/**" access="permitAll"/>
        <headers>
            <xss-protection disabled="true"/>
            <header ref="cspHeaderWriter"/>
        </headers>
        <csrf disabled="true"/>
        <custom-filter before="FORM_LOGIN_FILTER" ref="jwtAuthFilter"/>
        <custom-filter after="FORM_LOGIN_FILTER" ref="redisTokenFilter" />
    </http>

    <!-- Beans -->
    <beans:bean id="redisTokenFilter" class="com.divami.cadence.ims.redis.RedisTokenFilter" />

    <!-- <beans:bean id="jwtUtil" class="com.divami.cadence.ims.jwt.JwtUtil" /> -->

    <beans:bean id="jwtAuthEntryPoint" class="com.divami.cadence.ims.jwt.JwtAuthEntryPoint" />

    <beans:bean id="jwtAuthSuccessHandler" class="com.divami.cadence.ims.jwt.JwtAuthSuccessHandler" />

    <beans:bean id="jwtAuthManager" class="com.divami.cadence.ims.jwt.JwtAuthManager" />

    <beans:bean id="jwtAuthFilter" class="com.divami.cadence.ims.jwt.JwtAuthFilter">
        <beans:property name="authenticationManager" ref="authManager"/>
        <beans:property name="authenticationSuccessHandler" ref="jwtAuthSuccessHandler"/>
    </beans:bean>

    <!-- Define a RegexRequestMatcher bean -->
    <beans:bean id="secureMatcher"
                class="org.springframework.security.web.util.matcher.RegexRequestMatcher">
        <!-- Matches paths like /user/profile but excludes extensions like .json, .xml -->
        <!--        <beans:constructor-arg value="^/(?!register)(?!.*\\.[a-zA-Z0-9]+$)(?:[^/.]+/?)*$"/>-->
        <beans:constructor-arg value="^/(?!register)(?:[^/]+/?)*$"/>
        <beans:constructor-arg>
            <beans:null/>
        </beans:constructor-arg>
    </beans:bean>

    <!-- Define a RegexRequestMatcher bean -->
    <beans:bean id="registerMatcher"
                class="org.springframework.security.web.util.matcher.RegexRequestMatcher">
        <beans:constructor-arg value="^/register(?:/[^/.]+)*$"/>
        <beans:constructor-arg value="GET"/>
    </beans:bean>

    <beans:bean id="cspHeaderWriter"
                class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
        <beans:constructor-arg>
            <beans:bean class="org.springframework.security.web.util.matcher.OrRequestMatcher">
                <beans:constructor-arg>
                    <beans:list>
                        <beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                            <beans:constructor-arg value="/**/login"/>
                        </beans:bean>
                        <beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                            <beans:constructor-arg value="/**/validateLogin"/>
                        </beans:bean>
                        <beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                            <beans:constructor-arg value="/register/**"/>
                        </beans:bean>
                        <beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                            <beans:constructor-arg value="/profile/**/forgotUserName"/>
                        </beans:bean>
                        <beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                            <beans:constructor-arg value="/profile/**/forgotPassword"/>
                        </beans:bean>
                        <beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                            <beans:constructor-arg value="/profile/**/setNewPassword"/>
                        </beans:bean>
                        <beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                            <beans:constructor-arg value="/**/checkForUpdates"/>
                        </beans:bean>
                        <beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                            <beans:constructor-arg value="/**"/>
                        </beans:bean>
                    </beans:list>
                </beans:constructor-arg>
            </beans:bean>
        </beans:constructor-arg>

        <beans:constructor-arg>
            <beans:bean class="org.springframework.security.web.header.writers.StaticHeadersWriter">
                <beans:constructor-arg value="Content-Security-Policy"/>
                <beans:constructor-arg>
                    <beans:list>
                        <beans:value>default-src 'none';</beans:value>
                    </beans:list>
                </beans:constructor-arg>
            </beans:bean>
        </beans:constructor-arg>
    </beans:bean>

    <!--    This block is kept only for future reference. Xss-Protection is disabled without adding this header-->
    <beans:bean id="xssHeaderWriter"
                class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
        <beans:constructor-arg>
            <beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                <beans:constructor-arg value="/**"/>
            </beans:bean>
        </beans:constructor-arg>
        <beans:constructor-arg>
            <beans:bean class="org.springframework.security.web.header.writers.StaticHeadersWriter">
                <beans:constructor-arg value="X-XSS-Protection"/>
                <beans:constructor-arg>
                    <beans:list>
                        <beans:value>0</beans:value>
                    </beans:list>
                </beans:constructor-arg>
            </beans:bean>
        </beans:constructor-arg>
    </beans:bean>
    <authentication-manager alias="authManager">
        <authentication-provider ref="jwtAuthManager" />
    </authentication-manager>

</beans:beans>