/*
 * 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.URL;
import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
import org.apache.dubbo.rpc.cluster.router.mesh.util.MeshRuleListener;

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

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

import static org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleConstants.MESH_RULE_DATA_ID_SUFFIX;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

class MeshAppRuleListenerTest {

    private static final String rule1 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" + "kind: DestinationRule\n"
            + "metadata: { name: demo-route }\n"
            + "spec:\n"
            + "  host: demo\n"
            + "  subsets:\n"
            + "    - labels: { env-sign: xxx, tag1: hello }\n"
            + "      name: isolation\n"
            + "    - labels: { env-sign: yyy }\n"
            + "      name: testing-trunk\n"
            + "    - labels: { env-sign: zzz }\n"
            + "      name: testing\n"
            + "  trafficPolicy:\n"
            + "    loadBalancer: { simple: ROUND_ROBIN }\n"
            + "\n";
    private static final String rule2 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" + "kind: VirtualService\n"
            + "metadata: { name: demo-route }\n"
            + "spec:\n"
            + "  dubbo:\n"
            + "    - routedetail:\n"
            + "        - match:\n"
            + "            - sourceLabels: {trafficLabel: xxx}\n"
            + "          name: xxx-project\n"
            + "          route:\n"
            + "            - destination: {host: demo, subset: isolation}\n"
            + "        - match:\n"
            + "            - sourceLabels: {trafficLabel: testing-trunk}\n"
            + "          name: testing-trunk\n"
            + "          route:\n"
            + "            - destination: {host: demo, subset: testing-trunk}\n"
            + "        - name: testing\n"
            + "          route:\n"
            + "            - destination: {host: demo, subset: testing}\n"
            + "      services:\n"
            + "        - {regex: ccc}\n"
            + "  hosts: [demo]\n";
    private static final String rule3 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" + "kind: DestinationRule\n"
            + "spec:\n"
            + "  host: demo\n"
            + "  subsets:\n"
            + "    - labels: { env-sign: xxx, tag1: hello }\n"
            + "      name: isolation\n"
            + "    - labels: { env-sign: yyy }\n"
            + "      name: testing-trunk\n"
            + "    - labels: { env-sign: zzz }\n"
            + "      name: testing\n"
            + "  trafficPolicy:\n"
            + "    loadBalancer: { simple: ROUND_ROBIN }\n";
    private static final String rule4 = "apiVersionservice.dubbo.apache.org/v1alpha1\n";
    private static final String rule5 = "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 rule6 = "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 rule7 = "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 rule8 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" + "kind: VirtualService\n"
            + "metadata: { name: demo-route.Type2 }\n"
            + "spec:\n"
            + "  hosts: [demo]\n";

    @Test
    void testStandard() {
        MeshAppRuleListener meshAppRuleListener = new MeshAppRuleListener("demo-route");

        StandardMeshRuleRouter standardMeshRuleRouter = Mockito.spy(new StandardMeshRuleRouter(URL.valueOf("")));
        meshAppRuleListener.register(standardMeshRuleRouter);

        meshAppRuleListener.receiveConfigInfo(rule1 + "---\n" + rule2);

        ArgumentCaptor<String> appCaptor = ArgumentCaptor.forClass(String.class);
        ArgumentCaptor<List<Map<String, Object>>> ruleCaptor = ArgumentCaptor.forClass(List.class);

        verify(standardMeshRuleRouter, times(1)).onRuleChange(appCaptor.capture(), ruleCaptor.capture());

        List<Map<String, Object>> rulesReceived = ruleCaptor.getValue();
        assertEquals(2, rulesReceived.size());
        Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
        Assertions.assertTrue(rulesReceived.contains(yaml.load(rule1)));
        Assertions.assertTrue(rulesReceived.contains(yaml.load(rule2)));

        Assertions.assertEquals("demo-route", appCaptor.getValue());

        meshAppRuleListener.receiveConfigInfo("");
        verify(standardMeshRuleRouter, times(1)).clearRule("demo-route");
    }

    @Test
    void register() {
        MeshAppRuleListener meshAppRuleListener = new MeshAppRuleListener("demo-route");

        StandardMeshRuleRouter standardMeshRuleRouter1 = Mockito.spy(new StandardMeshRuleRouter(URL.valueOf("")));
        StandardMeshRuleRouter standardMeshRuleRouter2 = Mockito.spy(new StandardMeshRuleRouter(URL.valueOf("")));

        meshAppRuleListener.register(standardMeshRuleRouter1);

        Assertions.assertEquals(
                1,
                meshAppRuleListener
                        .getMeshRuleDispatcher()
                        .getListenerMap()
                        .get(MeshRuleConstants.STANDARD_ROUTER_KEY)
                        .size());
        meshAppRuleListener.receiveConfigInfo(rule1 + "---\n" + rule2);
        meshAppRuleListener.register(standardMeshRuleRouter2);
        Assertions.assertEquals(
                2,
                meshAppRuleListener
                        .getMeshRuleDispatcher()
                        .getListenerMap()
                        .get(MeshRuleConstants.STANDARD_ROUTER_KEY)
                        .size());

        ArgumentCaptor<String> appCaptor = ArgumentCaptor.forClass(String.class);
        ArgumentCaptor<List<Map<String, Object>>> ruleCaptor = ArgumentCaptor.forClass(List.class);

        verify(standardMeshRuleRouter1, times(1)).onRuleChange(appCaptor.capture(), ruleCaptor.capture());

        List<Map<String, Object>> rulesReceived = ruleCaptor.getValue();
        assertEquals(2, rulesReceived.size());
        Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
        Assertions.assertTrue(rulesReceived.contains(yaml.load(rule1)));
        Assertions.assertTrue(rulesReceived.contains(yaml.load(rule2)));

        Assertions.assertEquals("demo-route", appCaptor.getValue());

        verify(standardMeshRuleRouter2, times(1)).onRuleChange(appCaptor.capture(), ruleCaptor.capture());
        rulesReceived = ruleCaptor.getValue();
        assertEquals(2, rulesReceived.size());
        Assertions.assertTrue(rulesReceived.contains(yaml.load(rule1)));
        Assertions.assertTrue(rulesReceived.contains(yaml.load(rule2)));

        Assertions.assertEquals("demo-route", appCaptor.getValue());
    }

    @Test
    void unregister() {
        MeshAppRuleListener meshAppRuleListener = new MeshAppRuleListener("demo-route");

        StandardMeshRuleRouter standardMeshRuleRouter1 = Mockito.spy(new StandardMeshRuleRouter(URL.valueOf("")));
        StandardMeshRuleRouter standardMeshRuleRouter2 = Mockito.spy(new StandardMeshRuleRouter(URL.valueOf("")));

        meshAppRuleListener.register(standardMeshRuleRouter1);

        Assertions.assertEquals(
                1,
                meshAppRuleListener
                        .getMeshRuleDispatcher()
                        .getListenerMap()
                        .get(MeshRuleConstants.STANDARD_ROUTER_KEY)
                        .size());
        meshAppRuleListener.receiveConfigInfo(rule1 + "---\n" + rule2);
        meshAppRuleListener.register(standardMeshRuleRouter2);
        Assertions.assertEquals(
                2,
                meshAppRuleListener
                        .getMeshRuleDispatcher()
                        .getListenerMap()
                        .get(MeshRuleConstants.STANDARD_ROUTER_KEY)
                        .size());

        meshAppRuleListener.unregister(standardMeshRuleRouter1);
        Assertions.assertEquals(
                1,
                meshAppRuleListener
                        .getMeshRuleDispatcher()
                        .getListenerMap()
                        .get(MeshRuleConstants.STANDARD_ROUTER_KEY)
                        .size());

        meshAppRuleListener.unregister(standardMeshRuleRouter2);
        Assertions.assertEquals(
                0, meshAppRuleListener.getMeshRuleDispatcher().getListenerMap().size());
    }

    @Test
    void process() {
        MeshAppRuleListener meshAppRuleListener = new MeshAppRuleListener("demo-route");

        StandardMeshRuleRouter standardMeshRuleRouter = Mockito.spy(new StandardMeshRuleRouter(URL.valueOf("")));
        meshAppRuleListener.register(standardMeshRuleRouter);

        ConfigChangedEvent configChangedEvent = new ConfigChangedEvent(
                "demo-route" + MESH_RULE_DATA_ID_SUFFIX,
                DynamicConfiguration.DEFAULT_GROUP,
                rule1 + "---\n" + rule2,
                ConfigChangeType.ADDED);

        meshAppRuleListener.process(configChangedEvent);

        ArgumentCaptor<String> appCaptor = ArgumentCaptor.forClass(String.class);
        ArgumentCaptor<List<Map<String, Object>>> ruleCaptor = ArgumentCaptor.forClass(List.class);

        verify(standardMeshRuleRouter, times(1)).onRuleChange(appCaptor.capture(), ruleCaptor.capture());

        List<Map<String, Object>> rulesReceived = ruleCaptor.getValue();
        assertEquals(2, rulesReceived.size());
        Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
        Assertions.assertTrue(rulesReceived.contains(yaml.load(rule1)));
        Assertions.assertTrue(rulesReceived.contains(yaml.load(rule2)));

        configChangedEvent = new ConfigChangedEvent(
                "demo-route" + MESH_RULE_DATA_ID_SUFFIX,
                DynamicConfiguration.DEFAULT_GROUP,
                rule1 + "---\n" + rule2,
                ConfigChangeType.MODIFIED);

        meshAppRuleListener.process(configChangedEvent);

        verify(standardMeshRuleRouter, times(2)).onRuleChange(appCaptor.capture(), ruleCaptor.capture());

        rulesReceived = ruleCaptor.getValue();
        assertEquals(2, rulesReceived.size());
        Assertions.assertTrue(rulesReceived.contains(yaml.load(rule1)));
        Assertions.assertTrue(rulesReceived.contains(yaml.load(rule2)));

        configChangedEvent = new ConfigChangedEvent(
                "demo-route" + MESH_RULE_DATA_ID_SUFFIX,
                DynamicConfiguration.DEFAULT_GROUP,
                "",
                ConfigChangeType.DELETED);
        meshAppRuleListener.process(configChangedEvent);

        verify(standardMeshRuleRouter, times(1)).clearRule("demo-route");
    }

    @Test
    void testUnknownRule() {
        MeshAppRuleListener meshAppRuleListener = new MeshAppRuleListener("demo-route");

        StandardMeshRuleRouter standardMeshRuleRouter = Mockito.spy(new StandardMeshRuleRouter(URL.valueOf("")));

        meshAppRuleListener.register(standardMeshRuleRouter);

        meshAppRuleListener.receiveConfigInfo(rule3 + "---\n" + rule2);
        ArgumentCaptor<String> appCaptor = ArgumentCaptor.forClass(String.class);
        ArgumentCaptor<List<Map<String, Object>>> ruleCaptor = ArgumentCaptor.forClass(List.class);

        verify(standardMeshRuleRouter, times(1)).onRuleChange(appCaptor.capture(), ruleCaptor.capture());

        List<Map<String, Object>> rulesReceived = ruleCaptor.getValue();
        assertEquals(1, rulesReceived.size());
        Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
        Assertions.assertTrue(rulesReceived.contains(yaml.load(rule2)));

        meshAppRuleListener.receiveConfigInfo(rule1 + "---\n" + rule4);

        verify(standardMeshRuleRouter, times(2)).onRuleChange(appCaptor.capture(), ruleCaptor.capture());

        rulesReceived = ruleCaptor.getValue();
        assertEquals(1, rulesReceived.size());
        Assertions.assertTrue(rulesReceived.contains(yaml.load(rule1)));

        meshAppRuleListener.receiveConfigInfo(rule3 + "---\n" + rule4);
        verify(standardMeshRuleRouter, times(1)).clearRule("demo-route");
    }

    @Test
    void testMultipleRule() {
        MeshAppRuleListener meshAppRuleListener = new MeshAppRuleListener("demo-route");

        AtomicInteger count = new AtomicInteger(0);
        MeshRuleListener listener1 = new MeshRuleListener() {
            @Override
            public void onRuleChange(String appName, List<Map<String, Object>> rules) {
                Assertions.assertEquals("demo-route", appName);
                Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
                Assertions.assertTrue(rules.contains(yaml.load(rule5)));
                Assertions.assertTrue(rules.contains(yaml.load(rule6)));
                count.incrementAndGet();
            }

            @Override
            public void clearRule(String appName) {}

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

        MeshRuleListener listener2 = new MeshRuleListener() {
            @Override
            public void onRuleChange(String appName, List<Map<String, Object>> rules) {
                Assertions.assertEquals("demo-route", appName);
                Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
                Assertions.assertTrue(rules.contains(yaml.load(rule7)));
                Assertions.assertTrue(rules.contains(yaml.load(rule8)));
                count.incrementAndGet();
            }

            @Override
            public void clearRule(String appName) {}

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

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

            @Override
            public void clearRule(String appName) {
                Assertions.assertEquals("demo-route", appName);
                count.incrementAndGet();
            }

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

        StandardMeshRuleRouter standardMeshRuleRouter = Mockito.spy(new StandardMeshRuleRouter(URL.valueOf("")));

        meshAppRuleListener.register(standardMeshRuleRouter);
        meshAppRuleListener.register(listener1);
        meshAppRuleListener.register(listener2);
        meshAppRuleListener.register(listener4);

        meshAppRuleListener.receiveConfigInfo(
                rule1 + "---\n" + rule2 + "---\n" + rule5 + "---\n" + rule6 + "---\n" + rule7 + "---\n" + rule8);
        ArgumentCaptor<String> appCaptor = ArgumentCaptor.forClass(String.class);
        ArgumentCaptor<List<Map<String, Object>>> ruleCaptor = ArgumentCaptor.forClass(List.class);

        verify(standardMeshRuleRouter, times(1)).onRuleChange(appCaptor.capture(), ruleCaptor.capture());

        List<Map<String, Object>> rulesReceived = ruleCaptor.getValue();
        assertEquals(2, rulesReceived.size());
        Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
        Assertions.assertTrue(rulesReceived.contains(yaml.load(rule1)));
        Assertions.assertTrue(rulesReceived.contains(yaml.load(rule2)));

        Assertions.assertEquals("demo-route", appCaptor.getValue());

        Assertions.assertEquals(3, count.get());
    }
}
