/*
 * 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.
 */

package org.apache.ignite.springdata;

import java.io.Serializable;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.client.IgniteClient;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.ClientConfiguration;
import org.apache.ignite.configuration.ClientConnectorConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
import org.apache.ignite.springdata.misc.PersonRepository;
import org.apache.ignite.springdata22.repository.IgniteRepository;
import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;

import static org.apache.ignite.testframework.GridTestUtils.assertThrowsAnyCause;
import static org.springframework.context.annotation.FilterType.ASSIGNABLE_TYPE;

/** Tests Spring Data repository cluster connection configurations. */
public class IgniteSpringDataConnectionConfigurationTest extends GridCommonAbstractTest {
    /** */
    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);

    /** */
    private static final String CACHE_NAME = "PersonCache";

    /** */
    private static final int CLI_CONN_PORT = 10810;

    /** */
    private static final String CLI_NAME = "cli-node";

    /** */
    private static final String SRV_NAME = "srv-node";

    /** */
    private static final String LOCAL_HOST = "127.0.0.1";

    /** Tests repository configuration in case {@link IgniteConfiguration} is used to access the Ignite cluster. */
    @Test
    public void testRepositoryWithIgniteConfiguration() {
        checkRepositoryConfiguration(IgniteConfigurationApplication.class, IgniteConfigRepository.class);

        assertClientNodeIsStopped();
    }

    /** Tests repository configuration in case {@link ClientConfiguration} is used to access the Ignite cluster. */
    @Test
    public void testRepositoryWithClientConfiguration() {
        checkRepositoryConfiguration(ClientConfigurationApplication.class, IgniteClientConfigRepository.class);
    }

    /** Tests repository configuration in case {@link Ignite} with non default is used to access the Ignite cluster. */
    @Test
    public void testRepositoryWithoutIgniteInstanceParameter() {
        checkRepositoryConfiguration(DefaultIgniteBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
    }

    /** Tests repository configuration in case {@link IgniteClient} with non default name is used to access the Ignite cluster. */
    @Test
    public void testRepositoryWithoutIgniteClientInstanceParameter() {
        checkRepositoryConfiguration(DefaultIgniteClientBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
    }

    /** Tests repository configuration in case {@link ClientConfiguration} with non default name is used to access the Ignite cluster. */
    @Test
    public void testRepositoryWithoutIgnitClientConfigurationParameter() {
        checkRepositoryConfiguration(DefaultIgniteClientConfigurationBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
    }

    /** Tests repository configuration in case {@link IgniteConfiguration} with non default name is used to access the Ignite cluster. */
    @Test
    public void testRepositoryWithoutIgniteConfigurationParameter() {
        checkRepositoryConfiguration(DefaultIgniteConfigurationBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
    }

    /**
     * Tests repository configuration in case {@link IgniteConfiguration} that refers to existing Ignite node instance
     * used to access the Ignite cluster.
     */
    @Test
    public void testRepositoryWithExistingIgniteInstance() throws Exception {
        try (Ignite ignored = startGrid(getIgniteConfiguration(CLI_NAME, true))) {
            checkRepositoryConfiguration(IgniteConfigurationApplication.class, IgniteConfigRepository.class);

            assertNotNull(Ignition.ignite(CLI_NAME));
        }
    }

    /** Tests repository configuration in case specified cache name is invalid. */
    @Test
    public void testRepositoryWithInvalidCacheNameConfiguration() {
        try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext()) {
            ctx.register(InvalidCacheNameApplication.class);

            assertThrowsAnyCause(log,
                () -> {
                    ctx.refresh();

                    return null;
                },
                IllegalArgumentException.class,
                "Cache 'invalidCache' not found for repository interface" +
                    " org.apache.ignite.springdata.IgniteSpringDataConnectionConfigurationTest$InvalidCacheNameRepository." +
                    " Please, add a cache configuration to ignite configuration or pass autoCreateCache=true to" +
                    " org.apache.ignite.springdata22.repository.config.RepositoryConfig annotation.");
        }

        assertClientNodeIsStopped();
    }

    /** {@inheritDoc} */
    @Override protected void afterTest() throws Exception {
        super.afterTest();

        grid(SRV_NAME).cache(CACHE_NAME).clear();
    }

    /** */
    private void assertClientNodeIsStopped() {
        assertFalse(Ignition.allGrids().stream().map(Ignite::name).anyMatch(CLI_NAME::equals));
    }

    /** {@inheritDoc} */
    @Override protected void beforeTestsStarted() throws Exception {
        super.beforeTestsStarted();

        startGrid(getIgniteConfiguration(SRV_NAME, false));
    }

    /**
     * Checks that repository created based on specified Spring application configuration is properly initialized and
     * got access to the Ignite cluster.
     */
    private void checkRepositoryConfiguration(
        Class<?> cfgCls,
        Class<? extends IgniteRepository<Object, Serializable>> repoCls
    ) {
        try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext()) {
            ctx.register(cfgCls);
            ctx.refresh();

            IgniteRepository<Object, Serializable> repo = ctx.getBean(repoCls);

            IgniteCache<Object, Serializable> cache = grid(SRV_NAME).cache(CACHE_NAME);

            assertEquals(0, repo.count());
            assertEquals(0, cache.size());

            int key = 0;

            repo.save(key, "1");

            assertEquals(1, repo.count());
            assertNotNull(cache.get(key));
        }
    }

    /**
     * Spring Application configuration for repository testing in case {@link IgniteConfiguration} is used
     * for accessing the cluster.
     */
    @Configuration
    @EnableIgniteRepositories(
        considerNestedRepositories = true,
        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = InvalidCacheNameRepository.class))
    public static class InvalidCacheNameApplication {
        /** Ignite configuration bean. */
        @Bean
        public IgniteConfiguration igniteConfiguration() {
            return getIgniteConfiguration(CLI_NAME, true);
        }
    }

    /**
     * Spring Application configuration for repository testing in case {@link IgniteConfiguration} is used
     * for accessing the cluster.
     */
    @Configuration
    @EnableIgniteRepositories(
        considerNestedRepositories = true,
        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteConfigRepository.class))
    public static class IgniteConfigurationApplication {
        /** Ignite configuration bean. */
        @Bean
        public IgniteConfiguration igniteConfiguration() {
            return getIgniteConfiguration(CLI_NAME, true);
        }
    }

    /**
     * Spring Application configuration for repository testing in case {@link ClientConfiguration} is used
     * for accessing the cluster.
     */
    @Configuration
    @EnableIgniteRepositories(
        considerNestedRepositories = true,
        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteClientConfigRepository.class))
    public static class ClientConfigurationApplication {
        /** Ignite client configuration bean. */
        @Bean
        public ClientConfiguration clientConfiguration() {
            return new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT);
        }
    }

    /**
     * Spring Application configuration for repository testing in case if Ignite bean name was not provided
     * through {@link RepositoryConfig#igniteInstance()} ()}.
     */
    @Configuration
    @EnableIgniteRepositories(
        considerNestedRepositories = true,
        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
    )
    public static class DefaultIgniteBeanApplication {
        /** Ignite bean. */
        @Bean
        public Ignite someIgnite() {
            return Ignition.start(getIgniteConfiguration("test", false));
        }
    }

    /**
     * Spring Application configuration for repository testing in case if IgniteClient bean name was not provided
     * through {@link RepositoryConfig#igniteInstance()} ()}.
     */
    @Configuration
    @EnableIgniteRepositories(
        considerNestedRepositories = true,
        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
    )
    public static class DefaultIgniteClientBeanApplication {
        /** Ignite client bean. */
        @Bean
        public IgniteClient someIgnite() {
            return Ignition.startClient(new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT));
        }
    }

    /**
     * Spring Application configuration for repository testing in case if ClientConfiguration bean name was not provided
     * through {@link RepositoryConfig#igniteCfg()}.
     */
    @Configuration
    @EnableIgniteRepositories(
        considerNestedRepositories = true,
        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
    )
    public static class DefaultIgniteClientConfigurationBeanApplication {
        /** Ignite client configuration bean. */
        @Bean
        public ClientConfiguration someCfg() {
            return new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT);
        }
    }

    /**
     * Spring Application configuration for repository testing in case if IgniteConfiguration bean name was not provided
     * through {@link RepositoryConfig#igniteCfg()}.
     */
    @Configuration
    @EnableIgniteRepositories(
        considerNestedRepositories = true,
        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
    )
    public static class DefaultIgniteConfigurationBeanApplication {
        /** Ignite client configuration bean. */
        @Bean
        public IgniteConfiguration someCfg() {
            return getIgniteConfiguration("test", false);
        }
    }

    /** Repository for testing configuration approach through default ignite beans. */
    @RepositoryConfig(cacheName = "PersonCache")
    public interface IgniteRepositoryWithoutExplicitIgnite extends IgniteRepository<Object, Serializable> {
        // No-op.
    }

    /** Repository for testing configuration approach through {@link IgniteConfiguration}. */
    @RepositoryConfig(cacheName = "PersonCache", igniteCfg = "igniteConfiguration")
    public interface IgniteConfigRepository extends IgniteRepository<Object, Serializable> {
        // No-op.
    }

    /** Repository for testing repository configuration approach through {@link ClientConfiguration}. */
    @RepositoryConfig(cacheName = "PersonCache", igniteCfg = "clientConfiguration")
    public interface IgniteClientConfigRepository extends IgniteRepository<Object, Serializable> {
        // No-op.
    }

    /** Repository for testing application behavior in case invalid cache is specified in the repository configuration. */
    @RepositoryConfig(cacheName = "invalidCache", igniteCfg = "igniteConfiguration")
    public interface InvalidCacheNameRepository extends IgniteRepository<Object, Serializable> {
        // No-op.
    }

    /** */
    private static IgniteConfiguration getIgniteConfiguration(String name, boolean clientMode) {
        return new IgniteConfiguration()
            .setIgniteInstanceName(name)
            .setClientMode(clientMode)
            .setLocalHost(LOCAL_HOST)
            .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(IP_FINDER))
            .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(CLI_CONN_PORT))
            .setCacheConfiguration(new CacheConfiguration<>(CACHE_NAME));
    }
}
