/*
 * Copyright 2015-present Open Networking Laboratory
 *
 * Licensed 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.onosproject.net.config.impl;

import java.util.Set;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onosproject.event.EventDeliveryServiceAdapter;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.config.SubjectFactory;
import org.onosproject.net.NetTestTools;
import org.onosproject.store.config.impl.DistributedNetworkConfigStore;
import org.onosproject.store.service.TestStorageService;

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.testing.EqualsTester;

/**
 * Unit tests for network config registry.
 */
public class NetworkConfigManagerTest {
    private NetworkConfigManager manager;
    private NetworkConfigRegistry registry;
    private NetworkConfigService configService;
    private DistributedNetworkConfigStore configStore;

    /**
     * Config classes for testing.
     */
    public class BasicConfig1 extends Config<String> { }
    public class BasicConfig2 extends Config<String> { }

    public class MockSubjectFactory extends SubjectFactory<String> {
        protected MockSubjectFactory(Class<String> subjectClass, String subjectKey) {
            super(subjectClass, subjectKey);
        }

        @Override
        public String createSubject(String subjectKey) {
            return subjectKey + "-subject";
        }
    }

    /**
     * Config factory classes for testing.
     */
    public class MockConfigFactory1 extends ConfigFactory<String, BasicConfig1> {
        protected MockConfigFactory1(SubjectFactory<String> subjectFactory,
                                    Class<BasicConfig1> configClass, String configKey) {
            super(subjectFactory, configClass, configKey);
        }
        @Override
        public BasicConfig1 createConfig() {
            return new BasicConfig1();
        }
    }

    public class MockConfigFactory2 extends ConfigFactory<String, BasicConfig2> {
        protected MockConfigFactory2(SubjectFactory<String> subjectFactory,
                                    Class<BasicConfig2> configClass, String configKey) {
            super(subjectFactory, configClass, configKey);
        }
        @Override
        public BasicConfig2 createConfig() {
            return new BasicConfig2();
        }
    }

    MockSubjectFactory factory1 = new MockSubjectFactory(String.class,
            "key1");
    MockSubjectFactory factory2 = new MockSubjectFactory(String.class,
            "key2");

    MockConfigFactory1 config1Factory = new MockConfigFactory1(factory1,
            BasicConfig1.class, "config1");
    MockConfigFactory2 config2Factory = new MockConfigFactory2(factory2,
            BasicConfig2.class, "config2");


    @Before
    public void setUp() throws Exception {
        configStore = new DistributedNetworkConfigStore();
        TestUtils.setField(configStore, "storageService", new TestStorageService());
        configStore.activate();
        manager = new NetworkConfigManager();
        manager.store = configStore;
        NetTestTools.injectEventDispatcher(manager, new EventDeliveryServiceAdapter());
        manager.activate();
        registry = manager;
        configService = manager;
    }

    @After
    public void tearDown() {
        configStore.deactivate();
        manager.deactivate();
    }

    @Test
    public void testRegistry() {
        assertThat(registry.getConfigFactories(), hasSize(0));
        assertThat(registry.getConfigFactories(String.class), hasSize(0));
        assertThat(registry.getConfigFactory(BasicConfig1.class), nullValue());

        registry.registerConfigFactory(config1Factory);
        registry.registerConfigFactory(config2Factory);

        assertThat(registry.getConfigFactories(), hasSize(2));
        assertThat(registry.getConfigFactories(String.class), hasSize(2));

        ConfigFactory queried = registry.getConfigFactory(BasicConfig1.class);
        assertThat(queried, is(config1Factory));

        registry.unregisterConfigFactory(queried);
        //  Factory associations are not removed according to code documentation
        assertThat(registry.getConfigFactories(), hasSize(1));
        assertThat(registry.getConfigFactories(String.class), hasSize(1));
        assertThat(registry.getConfigFactory(BasicConfig1.class), nullValue());
    }

    @Test
    public void configIdEquals() {
        NetworkConfigManager.ConfigIdentifier id1 =
                new NetworkConfigManager.ConfigIdentifier("s1", "c1");
        NetworkConfigManager.ConfigIdentifier likeId1 =
                new NetworkConfigManager.ConfigIdentifier("s1", "c1");
        NetworkConfigManager.ConfigIdentifier id2 =
                new NetworkConfigManager.ConfigIdentifier("s1", "c2");
        NetworkConfigManager.ConfigIdentifier id3 =
                new NetworkConfigManager.ConfigIdentifier("s2", "c1");

        new EqualsTester().addEqualityGroup(id1, likeId1)
                .addEqualityGroup(id2)
                .addEqualityGroup(id3)
                .testEquals();
    }

    @Test
    public void configKeyEquals() {
        NetworkConfigManager.ConfigKey key1 =
                new NetworkConfigManager.ConfigKey(String.class, String.class);
        NetworkConfigManager.ConfigKey likeKey1 =
                new NetworkConfigManager.ConfigKey(String.class, String.class);
        NetworkConfigManager.ConfigKey key2 =
                new NetworkConfigManager.ConfigKey(String.class, Integer.class);
        NetworkConfigManager.ConfigKey key3 =
                new NetworkConfigManager.ConfigKey(Integer.class, String.class);

        new EqualsTester().addEqualityGroup(key1, likeKey1)
                .addEqualityGroup(key2)
                .addEqualityGroup(key3)
                .testEquals();
    }

    /**
     * Tests creation, query and removal of a factory.
     */
    @Test
    public void testAddConfig() {

        assertThat(configService.getSubjectFactory(String.class), nullValue());
        assertThat(configService.getSubjectFactory("key"), nullValue());

        registry.registerConfigFactory(config1Factory);
        registry.registerConfigFactory(config2Factory);
        configService.addConfig("configKey", BasicConfig1.class);

        Config newConfig = configService.getConfig("configKey", BasicConfig1.class);
        assertThat(newConfig, notNullValue());

        assertThat(configService.getSubjectFactory(String.class), notNullValue());
        assertThat(configService.getSubjectFactory("key1"), notNullValue());

        Set<Class> classes = configService.getSubjectClasses();
        assertThat(classes, hasSize(1));

        Set<String> subjectsForClass =
                configService.getSubjects(String.class);
        assertThat(subjectsForClass, hasSize(1));

        Set<String> subjectsForConfig =
                configService.getSubjects(String.class, BasicConfig1.class);
        assertThat(subjectsForConfig, hasSize(1));

        Class queriedConfigClass = configService.getConfigClass("key1", "config1");
        assertThat(queriedConfigClass == BasicConfig1.class, is(true));

        Set<? extends Config> configs = configService.getConfigs("configKey");
        assertThat(configs.size(), is(1));
        configs.forEach(c -> assertThat(c, instanceOf(BasicConfig1.class)));

        configService.removeConfig("configKey", BasicConfig1.class);
        Config newConfigAfterRemove = configService.getConfig("configKey", BasicConfig1.class);
        assertThat(newConfigAfterRemove, nullValue());
    }

    /**
     * Tests creation, query and removal of a factory.
     */
    @Test
    public void testApplyConfig() {

        assertThat(configService.getSubjectFactory(String.class), nullValue());
        assertThat(configService.getSubjectFactory("key"), nullValue());

        registry.registerConfigFactory(config1Factory);
        registry.registerConfigFactory(config2Factory);
        configService.applyConfig("configKey", BasicConfig1.class, new ObjectMapper().createObjectNode());

        Config newConfig = configService.getConfig("configKey", BasicConfig1.class);
        assertThat(newConfig, notNullValue());

        assertThat(configService.getSubjectFactory(String.class), notNullValue());
        assertThat(configService.getSubjectFactory("key1"), notNullValue());
    }
}
