/*
 * 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.dubbo.rpc.cluster.router.mesh.route;

import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository;
import org.apache.dubbo.rpc.cluster.router.mesh.util.MeshRuleListener;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ModuleModel;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

class MeshRuleManagerTest {
    private static final String rule1 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" + "kind: DestinationRule\n"
            + "metadata: { name: demo-route.Type1 }\n"
            + "spec:\n"
            + "  host: demo\n"
            + "\n";
    private static final String rule2 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" + "kind: VirtualService\n"
            + "metadata: { name: demo-route.Type1 }\n"
            + "spec:\n"
            + "  hosts: [demo]\n";
    private static final String rule3 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" + "kind: DestinationRule\n"
            + "metadata: { name: demo-route.Type2 }\n"
            + "spec:\n"
            + "  host: demo\n"
            + "\n";
    private static final String rule4 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" + "kind: VirtualService\n"
            + "metadata: { name: demo-route.Type2 }\n"
            + "spec:\n"
            + "  hosts: [demo]\n";

    private ModuleModel originModule;
    private ModuleModel moduleModel;
    private GovernanceRuleRepository ruleRepository;
    private Set<MeshEnvListenerFactory> envListenerFactories;

    @BeforeEach
    public void setup() {
        originModule = ApplicationModel.defaultModel().getDefaultModule();
        moduleModel = Mockito.spy(originModule);

        ruleRepository = Mockito.mock(GovernanceRuleRepository.class);
        when(moduleModel.getDefaultExtension(GovernanceRuleRepository.class)).thenReturn(ruleRepository);

        ExtensionLoader<MeshEnvListenerFactory> envListenerFactoryLoader = Mockito.mock(ExtensionLoader.class);
        envListenerFactories = new HashSet<>();
        when(envListenerFactoryLoader.getSupportedExtensionInstances()).thenReturn(envListenerFactories);
        when(moduleModel.getExtensionLoader(MeshEnvListenerFactory.class)).thenReturn(envListenerFactoryLoader);
    }

    @AfterEach
    public void teardown() {
        originModule.destroy();
    }

    @Test
    void testRegister1() {
        MeshRuleManager meshRuleManager = new MeshRuleManager(moduleModel);

        MeshRuleListener meshRuleListener1 = new MeshRuleListener() {
            @Override
            public void onRuleChange(String appName, List<Map<String, Object>> rules) {
                fail();
            }

            @Override
            public void clearRule(String appName) {}

            @Override
            public String ruleSuffix() {
                return "Type1";
            }
        };

        meshRuleManager.register("dubbo-demo", meshRuleListener1);

        assertEquals(1, meshRuleManager.getAppRuleListeners().size());
        verify(ruleRepository, times(1)).getRule("dubbo-demo.MESHAPPRULE", "dubbo", 5000L);

        MeshAppRuleListener meshAppRuleListener =
                meshRuleManager.getAppRuleListeners().values().iterator().next();
        verify(ruleRepository, times(1)).addListener("dubbo-demo.MESHAPPRULE", "dubbo", meshAppRuleListener);

        meshRuleManager.register("dubbo-demo", meshRuleListener1);
        assertEquals(1, meshRuleManager.getAppRuleListeners().size());

        MeshRuleListener meshRuleListener2 = new MeshRuleListener() {
            @Override
            public void onRuleChange(String appName, List<Map<String, Object>> rules) {
                fail();
            }

            @Override
            public void clearRule(String appName) {}

            @Override
            public String ruleSuffix() {
                return "Type2";
            }
        };
        meshRuleManager.register("dubbo-demo", meshRuleListener2);
        assertEquals(1, meshRuleManager.getAppRuleListeners().size());
        assertEquals(
                2, meshAppRuleListener.getMeshRuleDispatcher().getListenerMap().size());

        meshRuleManager.unregister("dubbo-demo", meshRuleListener1);
        assertEquals(1, meshRuleManager.getAppRuleListeners().size());
        assertEquals(
                1, meshAppRuleListener.getMeshRuleDispatcher().getListenerMap().size());

        meshRuleManager.unregister("dubbo-demo", meshRuleListener2);
        assertEquals(0, meshRuleManager.getAppRuleListeners().size());

        verify(ruleRepository, times(1)).removeListener("dubbo-demo.MESHAPPRULE", "dubbo", meshAppRuleListener);
    }

    @Test
    void testRegister2() {
        MeshRuleManager meshRuleManager = new MeshRuleManager(moduleModel);

        AtomicInteger invokeTimes = new AtomicInteger(0);
        MeshRuleListener meshRuleListener = new MeshRuleListener() {
            @Override
            public void onRuleChange(String appName, List<Map<String, Object>> rules) {
                assertEquals("dubbo-demo", appName);
                Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
                assertTrue(rules.contains(yaml.load(rule1)));
                assertTrue(rules.contains(yaml.load(rule2)));

                invokeTimes.incrementAndGet();
            }

            @Override
            public void clearRule(String appName) {}

            @Override
            public String ruleSuffix() {
                return "Type1";
            }
        };

        when(ruleRepository.getRule("dubbo-demo.MESHAPPRULE", "dubbo", 5000L)).thenReturn(rule1 + "---\n" + rule2);

        meshRuleManager.register("dubbo-demo", meshRuleListener);

        assertEquals(1, meshRuleManager.getAppRuleListeners().size());
        verify(ruleRepository, times(1)).getRule("dubbo-demo.MESHAPPRULE", "dubbo", 5000L);
        verify(ruleRepository, times(1))
                .addListener(
                        "dubbo-demo.MESHAPPRULE",
                        "dubbo",
                        meshRuleManager
                                .getAppRuleListeners()
                                .values()
                                .iterator()
                                .next());
        assertEquals(1, invokeTimes.get());

        meshRuleManager.register("dubbo-demo", meshRuleListener);
        assertEquals(1, meshRuleManager.getAppRuleListeners().size());
    }

    @Test
    void testRegister3() {
        MeshEnvListenerFactory meshEnvListenerFactory1 = Mockito.mock(MeshEnvListenerFactory.class);
        MeshEnvListenerFactory meshEnvListenerFactory2 = Mockito.mock(MeshEnvListenerFactory.class);

        MeshEnvListener meshEnvListener1 = Mockito.mock(MeshEnvListener.class);
        when(meshEnvListenerFactory1.getListener()).thenReturn(meshEnvListener1);
        MeshEnvListener meshEnvListener2 = Mockito.mock(MeshEnvListener.class);
        when(meshEnvListenerFactory2.getListener()).thenReturn(meshEnvListener2);

        envListenerFactories.add(meshEnvListenerFactory1);
        envListenerFactories.add(meshEnvListenerFactory2);

        MeshRuleManager meshRuleManager = new MeshRuleManager(moduleModel);

        MeshRuleListener meshRuleListener1 = new MeshRuleListener() {
            @Override
            public void onRuleChange(String appName, List<Map<String, Object>> rules) {
                fail();
            }

            @Override
            public void clearRule(String appName) {}

            @Override
            public String ruleSuffix() {
                return "Type1";
            }
        };

        when(meshEnvListener1.isEnable()).thenReturn(false);
        when(meshEnvListener2.isEnable()).thenReturn(true);

        meshRuleManager.register("dubbo-demo", meshRuleListener1);

        assertEquals(1, meshRuleManager.getAppRuleListeners().size());
        verify(ruleRepository, times(1)).getRule("dubbo-demo.MESHAPPRULE", "dubbo", 5000L);
        MeshAppRuleListener meshAppRuleListener =
                meshRuleManager.getAppRuleListeners().values().iterator().next();
        verify(ruleRepository, times(1)).addListener("dubbo-demo.MESHAPPRULE", "dubbo", meshAppRuleListener);

        verify(meshEnvListener2, times(1)).onSubscribe("dubbo-demo", meshAppRuleListener);

        meshRuleManager.register("dubbo-demo", meshRuleListener1);
        assertEquals(1, meshRuleManager.getAppRuleListeners().size());

        MeshRuleListener meshRuleListener2 = new MeshRuleListener() {
            @Override
            public void onRuleChange(String appName, List<Map<String, Object>> rules) {
                fail();
            }

            @Override
            public void clearRule(String appName) {}

            @Override
            public String ruleSuffix() {
                return "Type2";
            }
        };
        meshRuleManager.register("dubbo-demo", meshRuleListener2);
        assertEquals(1, meshRuleManager.getAppRuleListeners().size());
        assertEquals(
                2, meshAppRuleListener.getMeshRuleDispatcher().getListenerMap().size());

        meshRuleManager.unregister("dubbo-demo", meshRuleListener1);
        assertEquals(1, meshRuleManager.getAppRuleListeners().size());
        assertEquals(
                1, meshAppRuleListener.getMeshRuleDispatcher().getListenerMap().size());

        meshRuleManager.unregister("dubbo-demo", meshRuleListener2);
        assertEquals(0, meshRuleManager.getAppRuleListeners().size());

        verify(ruleRepository, times(1)).removeListener("dubbo-demo.MESHAPPRULE", "dubbo", meshAppRuleListener);
        verify(meshEnvListener2, times(1)).onUnSubscribe("dubbo-demo");
    }
}
