package org.apache.ignite.spring.sessions;

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.configuration.CacheConfiguration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatchers;

import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.session.FlushMode;
import org.springframework.session.IndexResolver;
import org.springframework.session.SaveMode;
import org.springframework.session.Session;
import org.springframework.session.config.SessionRepositoryCustomizer;
import org.springframework.test.util.ReflectionTestUtils;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;

/**
 * Tests for {@link IgniteHttpSessionConfiguration}.
 */
public class IgniteHttpSessionConfigurationTest {
    /** */
    private static final String MAP_NAME = "spring:test:sessions";

    /** */
    private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 600;

    /** */
    private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

    /** */
    @AfterEach
    void closeContext() {
        if (this.context != null)
            this.context.close();
    }

    /** */
    @Test
    void noIgniteConfiguration() {
        assertThatExceptionOfType(BeanCreationException.class)
                .isThrownBy(() -> registerAndRefresh(NoIgniteConfiguration.class)).withMessageContaining("Ignite");
    }

    /** */
    @Test
    void defaultConfiguration() {
        registerAndRefresh(DefaultConfiguration.class);

        assertThat(this.context.getBean(IgniteIndexedSessionRepository.class)).isNotNull();
    }

    /** */
    @Test
    void customTableName() {
        registerAndRefresh(CustomSessionMapNameConfiguration.class);

        IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class);
        IgniteHttpSessionConfiguration configuration = this.context.getBean(IgniteHttpSessionConfiguration.class);
        assertThat(repository).isNotNull();
        assertThat(ReflectionTestUtils.getField(configuration, "sessionMapName")).isEqualTo(MAP_NAME);
    }

    /** */
    @Test
    void setCustomSessionMapName() {
        registerAndRefresh(BaseConfiguration.class, CustomSessionMapNameSetConfiguration.class);

        IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class);
        IgniteHttpSessionConfiguration configuration = this.context.getBean(IgniteHttpSessionConfiguration.class);
        assertThat(repository).isNotNull();
        assertThat(ReflectionTestUtils.getField(configuration, "sessionMapName")).isEqualTo(MAP_NAME);
    }

    /** */
    @Test
    void setCustomMaxInactiveIntervalInSeconds() {
        registerAndRefresh(BaseConfiguration.class, CustomMaxInactiveIntervalInSecondsSetConfiguration.class);

        IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class);
        assertThat(repository).isNotNull();
        assertThat(ReflectionTestUtils.getField(repository, "defaultMaxInactiveInterval"))
                .isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
    }

    /** */
    @Test
    void customMaxInactiveIntervalInSeconds() {
        registerAndRefresh(CustomMaxInactiveIntervalInSecondsConfiguration.class);

        IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class);
        assertThat(repository).isNotNull();
        assertThat(ReflectionTestUtils.getField(repository, "defaultMaxInactiveInterval"))
                .isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS);
    }

    /** */
    @Test
    void customFlushImmediately() {
        registerAndRefresh(CustomFlushImmediatelyConfiguration.class);

        IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class);
        assertThat(repository).isNotNull();
        assertThat(ReflectionTestUtils.getField(repository, "flushMode")).isEqualTo(FlushMode.IMMEDIATE);
    }

    /** */
    @Test
    void setCustomFlushImmediately() {
        registerAndRefresh(BaseConfiguration.class, CustomFlushImmediatelySetConfiguration.class);

        IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class);
        assertThat(repository).isNotNull();
        assertThat(ReflectionTestUtils.getField(repository, "flushMode")).isEqualTo(FlushMode.IMMEDIATE);
    }

    /** */
    @Test
    void customSaveModeAnnotation() {
        registerAndRefresh(BaseConfiguration.class, CustomSaveModeExpressionAnnotationConfiguration.class);
        assertThat(this.context.getBean(IgniteIndexedSessionRepository.class)).hasFieldOrPropertyWithValue("saveMode",
                SaveMode.ALWAYS);
    }

    /** */
    @Test
    void customSaveModeSetter() {
        registerAndRefresh(BaseConfiguration.class, CustomSaveModeExpressionSetterConfiguration.class);
        assertThat(this.context.getBean(IgniteIndexedSessionRepository.class)).hasFieldOrPropertyWithValue("saveMode",
                SaveMode.ALWAYS);
    }

    /** */
    @Test
    void qualifiedIgniteConfiguration() {
        registerAndRefresh(QualifiedIgniteConfiguration.class);

        IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class);
        Ignite ignite = this.context.getBean("qualifiedIgnite", Ignite.class);
        assertThat(repository).isNotNull();
        assertThat(ignite).isNotNull();
        assertThat(ReflectionTestUtils.getField(repository, "sessions"))
                .isEqualTo(QualifiedIgniteConfiguration.qualifiedIgniteSessions);
    }

    /** */
    @Test
    void primaryIgniteConfiguration() {
        registerAndRefresh(PrimaryIgniteConfiguration.class);

        IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class);
        Ignite ignite = this.context.getBean("primaryIgnite", Ignite.class);
        assertThat(repository).isNotNull();
        assertThat(ignite).isNotNull();
        assertThat(ReflectionTestUtils.getField(repository, "sessions"))
                .isEqualTo(PrimaryIgniteConfiguration.primaryIgniteSessions);
    }

    /** */
    @Test
    void qualifiedAndPrimaryIgniteConfiguration() {
        registerAndRefresh(QualifiedAndPrimaryIgniteConfiguration.class);

        IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class);
        Ignite ignite = this.context.getBean("qualifiedIgnite", Ignite.class);
        assertThat(repository).isNotNull();
        assertThat(ignite).isNotNull();
        assertThat(ReflectionTestUtils.getField(repository, "sessions"))
                .isEqualTo(QualifiedAndPrimaryIgniteConfiguration.qualifiedIgniteSessions);
    }

    /** */
    @Test
    void namedIgniteConfiguration() {
        registerAndRefresh(NamedIgniteConfiguration.class);

        IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class);
        Ignite ignite = this.context.getBean("ignite", Ignite.class);
        assertThat(repository).isNotNull();
        assertThat(ignite).isNotNull();
        assertThat(ReflectionTestUtils.getField(repository, "sessions"))
                .isEqualTo(NamedIgniteConfiguration.igniteSessions);
    }

    /** */
    @Test
    void multipleIgniteConfiguration() {
        assertThatExceptionOfType(BeanCreationException.class)
                .isThrownBy(() -> registerAndRefresh(MultipleIgniteConfiguration.class))
                .withMessageContaining("expected single matching bean but found 2");
    }

    /** */
    @Test
    void customIndexResolverConfiguration() {
        registerAndRefresh(CustomIndexResolverConfiguration.class);
        IgniteIndexedSessionRepository repository = this.context.getBean(IgniteIndexedSessionRepository.class);
        @SuppressWarnings("unchecked")
        IndexResolver<Session> indexResolver = this.context.getBean(IndexResolver.class);
        assertThat(repository).isNotNull();
        assertThat(indexResolver).isNotNull();
        assertThat(repository).hasFieldOrPropertyWithValue("indexResolver", indexResolver);
    }

    /** */
    @Test
    void sessionRepositoryCustomizer() {
        registerAndRefresh(SessionRepositoryCustomizerConfiguration.class);
        IgniteIndexedSessionRepository sessionRepository = this.context.getBean(IgniteIndexedSessionRepository.class);
        assertThat(sessionRepository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval",
                MAX_INACTIVE_INTERVAL_IN_SECONDS);
    }

    /** */
    private void registerAndRefresh(Class<?>... annotatedClasses) {
        this.context.register(annotatedClasses);
        this.context.refresh();
    }

    /** */
    @Configuration
    @EnableIgniteHttpSession
    static class NoIgniteConfiguration {

    }

    /** */
    static class BaseConfiguration {

        /** */
        @SuppressWarnings("unchecked")
        static IgniteCache<Object, Object> defaultIgniteSessions = mock(IgniteCache.class);

        /** */
        @Bean
        Ignite defaultIgnite() {
            Ignite ignite = mock(Ignite.class);
            given(ignite.getOrCreateCache(ArgumentMatchers.<CacheConfiguration<Object, Object>>any()))
                    .willReturn(defaultIgniteSessions);
            return ignite;
        }

    }

    /** */
    @Configuration
    @EnableIgniteHttpSession
    static class DefaultConfiguration extends BaseConfiguration {

    }

    /** */
    @Configuration
    @EnableIgniteHttpSession(sessionMapName = MAP_NAME)
    static class CustomSessionMapNameConfiguration extends BaseConfiguration {

    }

    /** */
    @Configuration
    static class CustomSessionMapNameSetConfiguration extends IgniteHttpSessionConfiguration {

        CustomSessionMapNameSetConfiguration() {
            setSessionMapName(MAP_NAME);
        }

    }

    /** */
    @Configuration
    static class CustomMaxInactiveIntervalInSecondsSetConfiguration extends IgniteHttpSessionConfiguration {

        CustomMaxInactiveIntervalInSecondsSetConfiguration() {
            setMaxInactiveIntervalInSeconds(MAX_INACTIVE_INTERVAL_IN_SECONDS);
        }

    }

    /** */
    @Configuration
    @EnableIgniteHttpSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
    static class CustomMaxInactiveIntervalInSecondsConfiguration extends BaseConfiguration {

    }

    /** */
    @Configuration
    static class CustomFlushImmediatelySetConfiguration extends IgniteHttpSessionConfiguration {

        CustomFlushImmediatelySetConfiguration() {
            setFlushMode(FlushMode.IMMEDIATE);
        }

    }

    /** */
    @EnableIgniteHttpSession(saveMode = SaveMode.ALWAYS)
    static class CustomSaveModeExpressionAnnotationConfiguration {

    }

    /** */
    @Configuration
    static class CustomSaveModeExpressionSetterConfiguration extends IgniteHttpSessionConfiguration {

        CustomSaveModeExpressionSetterConfiguration() {
            setSaveMode(SaveMode.ALWAYS);
        }

    }

    /** */
    @Configuration
    @EnableIgniteHttpSession(flushMode = FlushMode.IMMEDIATE)
    static class CustomFlushImmediatelyConfiguration extends BaseConfiguration {

    }

    /** */
    @Configuration
    @EnableIgniteHttpSession
    static class QualifiedIgniteConfiguration extends BaseConfiguration {

        /** */
        @SuppressWarnings("unchecked")
        static IgniteCache<Object, Object> qualifiedIgniteSessions = mock(IgniteCache.class);

        /** */
        @Bean
        @SpringSessionIgnite
        Ignite qualifiedIgnite() {
            Ignite ignite = mock(Ignite.class);
            given(ignite.getOrCreateCache(ArgumentMatchers.<CacheConfiguration<Object, Object>>any()))
                    .willReturn(qualifiedIgniteSessions);
            return ignite;
        }

    }

    /** */
    @Configuration
    @EnableIgniteHttpSession
    static class PrimaryIgniteConfiguration extends BaseConfiguration {

        /** */
        @SuppressWarnings("unchecked")
        static IgniteCache<Object, Object> primaryIgniteSessions = mock(IgniteCache.class);

        /** */
        @Bean
        @Primary
        Ignite primaryIgnite() {
            Ignite ignite = mock(Ignite.class);
            given(ignite.getOrCreateCache(ArgumentMatchers.<CacheConfiguration<Object, Object>>any()))
                    .willReturn(primaryIgniteSessions);
            return ignite;
        }

    }

    /** */
    @Configuration
    @EnableIgniteHttpSession
    static class QualifiedAndPrimaryIgniteConfiguration extends BaseConfiguration {

        /** */
        @SuppressWarnings("unchecked")
        static IgniteCache<Object, Object> qualifiedIgniteSessions = mock(IgniteCache.class);

        /** */
        @SuppressWarnings("unchecked")
        static IgniteCache<Object, Object> primaryIgniteSessions = mock(IgniteCache.class);

        /** */
        @Bean
        @SpringSessionIgnite
        Ignite qualifiedIgnite() {
            Ignite ignite = mock(Ignite.class);
            given(ignite.getOrCreateCache(ArgumentMatchers.<CacheConfiguration<Object, Object>>any()))
                    .willReturn(qualifiedIgniteSessions);
            return ignite;
        }

        /** */
        @Bean
        @Primary
        Ignite primaryIgnite() {
            Ignite ignite = mock(Ignite.class);
            given(ignite.getOrCreateCache(ArgumentMatchers.<CacheConfiguration<Object, Object>>any()))
                    .willReturn(primaryIgniteSessions);
            return ignite;
        }

    }

    /** */
    @Configuration
    @EnableIgniteHttpSession
    static class NamedIgniteConfiguration extends BaseConfiguration {

        /** */
        @SuppressWarnings("unchecked")
        static IgniteCache<Object, Object> igniteSessions = mock(IgniteCache.class);

        /** */
        @Bean
        Ignite ignite() {
            Ignite ignite = mock(Ignite.class);
            given(ignite.getOrCreateCache(ArgumentMatchers.<CacheConfiguration<Object, Object>>any()))
                    .willReturn(igniteSessions);
            return ignite;
        }

    }

    /** */
    @Configuration
    @EnableIgniteHttpSession
    static class MultipleIgniteConfiguration extends BaseConfiguration {

        /** */
        @SuppressWarnings("unchecked")
        static IgniteCache<Object, Object> secondaryIgniteSessions = mock(IgniteCache.class);

        /** */
        @Bean
        Ignite secondaryIgnite() {
            Ignite ignite = mock(Ignite.class);
            given(ignite.getOrCreateCache(ArgumentMatchers.<CacheConfiguration<Object, Object>>any()))
                    .willReturn(secondaryIgniteSessions);
            return ignite;
        }

    }

    /** */
    @EnableIgniteHttpSession
    static class CustomIndexResolverConfiguration extends BaseConfiguration {

        /** */
        @Bean
        @SuppressWarnings("unchecked")
        IndexResolver<Session> indexResolver() {
            return mock(IndexResolver.class);
        }

    }

    /** */
    @EnableIgniteHttpSession
    static class SessionRepositoryCustomizerConfiguration extends BaseConfiguration {

        /** */
        @Bean
        @Order(0)
        SessionRepositoryCustomizer<IgniteIndexedSessionRepository> sessionRepositoryCustomizerOne() {
            return (sessionRepository) -> sessionRepository.setDefaultMaxInactiveInterval(0);
        }

        /** */
        @Bean
        @Order(1)
        SessionRepositoryCustomizer<IgniteIndexedSessionRepository> sessionRepositoryCustomizerTwo() {
            return (sessionRepository) -> sessionRepository
                    .setDefaultMaxInactiveInterval(MAX_INACTIVE_INTERVAL_IN_SECONDS);
        }
    }
}

