/*
 * Copyright 1999-2011 Alibaba Group.
 *  
 * 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 com.alibaba.dubbo.monitor.dubbo;

import junit.framework.Assert;

import org.junit.Test;

import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.monitor.Monitor;
import com.alibaba.dubbo.monitor.MonitorFactory;
import com.alibaba.dubbo.monitor.MonitorService;
import com.alibaba.dubbo.rpc.Exporter;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Protocol;
import com.alibaba.dubbo.rpc.ProxyFactory;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcException;

/**
 * DubboMonitorTest
 * 
 * @author william.liangf
 */
public class DubboMonitorTest {
    
    private volatile URL lastStatistics;
    
    private final Invoker<MonitorService> monitorInvoker = new Invoker<MonitorService>() {
        public Class<MonitorService> getInterface() {
            return MonitorService.class;
        }
        public URL getUrl() {
            return URL.valueOf("dubbo://127.0.0.1:7070?interval=20");
        }
        public boolean isAvailable() {
            return false;
        }
        public Result invoke(Invocation invocation) throws RpcException {
            return null;
        }
        public void destroy() {
        }
    };
    
    private final MonitorService monitorService = new MonitorService() {

        public void count(URL statistics) {
            DubboMonitorTest.this.lastStatistics = statistics;
        }
        
    };
    
    @Test
    public void testCount() throws Exception {
        DubboMonitor monitor = new DubboMonitor(monitorInvoker, monitorService);
        URL statistics = new URL("dubbo", "10.20.153.10", 0)
            .addParameter(MonitorService.APPLICATION, "morgan")
            .addParameter(MonitorService.INTERFACE, "MemberService")
            .addParameter(MonitorService.METHOD, "findPerson")
            .addParameter(MonitorService.CONSUMER, "10.20.153.11")
            .addParameter(MonitorService.SUCCESS, 1)
            .addParameter(MonitorService.FAILURE, 0)
            .addParameter(MonitorService.ELAPSED, 3)
            .addParameter(MonitorService.MAX_ELAPSED, 3)
            .addParameter(MonitorService.CONCURRENT, 1)
            .addParameter(MonitorService.MAX_CONCURRENT, 1);
        monitor.count(statistics);
        while (lastStatistics == null) {
            Thread.sleep(10);
        }
        Assert.assertEquals(lastStatistics.getParameter(MonitorService.APPLICATION), "morgan");
        Assert.assertEquals(lastStatistics.getProtocol(), "dubbo");
        Assert.assertEquals(lastStatistics.getHost(), "10.20.153.10");
        Assert.assertEquals(lastStatistics.getParameter(MonitorService.APPLICATION), "morgan");
        Assert.assertEquals(lastStatistics.getParameter(MonitorService.INTERFACE), "MemberService");
        Assert.assertEquals(lastStatistics.getParameter(MonitorService.METHOD), "findPerson");
        Assert.assertEquals(lastStatistics.getParameter(MonitorService.CONSUMER), "10.20.153.11");
        Assert.assertEquals(lastStatistics.getParameter(MonitorService.SUCCESS), "1");
        Assert.assertEquals(lastStatistics.getParameter(MonitorService.FAILURE), "0");
        Assert.assertEquals(lastStatistics.getParameter(MonitorService.ELAPSED), "3");
        Assert.assertEquals(lastStatistics.getParameter(MonitorService.MAX_ELAPSED), "3");
        Assert.assertEquals(lastStatistics.getParameter(MonitorService.CONCURRENT), "1");
        Assert.assertEquals(lastStatistics.getParameter(MonitorService.MAX_CONCURRENT), "1");
        monitor.destroy();
    }
    
    @Test
    public void testMonitorFactory() throws Exception {
        MockMonitorService monitorService = new MockMonitorService();
        URL statistics = new URL("dubbo", "10.20.153.10", 0)
                .addParameter(MonitorService.APPLICATION, "morgan")
                .addParameter(MonitorService.INTERFACE, "MemberService")
                .addParameter(MonitorService.METHOD, "findPerson")
                .addParameter(MonitorService.CONSUMER, "10.20.153.11")
                .addParameter(MonitorService.SUCCESS, 1)
                .addParameter(MonitorService.FAILURE, 0)
                .addParameter(MonitorService.ELAPSED, 3)
                .addParameter(MonitorService.MAX_ELAPSED, 3)
                .addParameter(MonitorService.CONCURRENT, 1)
                .addParameter(MonitorService.MAX_CONCURRENT, 1);
        
        Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
        ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
        MonitorFactory monitorFactory = ExtensionLoader.getExtensionLoader(MonitorFactory.class).getAdaptiveExtension();

        Exporter<MonitorService> exporter = protocol.export(proxyFactory.getInvoker(monitorService, MonitorService.class, URL.valueOf("dubbo://127.0.0.1:17979/" + MonitorService.class.getName())));
        try {
            Monitor monitor = monitorFactory.getMonitor(URL.valueOf("dubbo://127.0.0.1:17979?interval=10"));
            try {
                monitor.count(statistics);
                int i = 0;
                while(monitorService.getStatistics() == null && i < 200) {
                    i ++;
                    Thread.sleep(10);
                }
                URL result = monitorService.getStatistics();
                Assert.assertEquals(1, result.getParameter(MonitorService.SUCCESS, 0));
                Assert.assertEquals(3, result.getParameter(MonitorService.ELAPSED, 0));
            } finally {
                monitor.destroy();
            }
        } finally {
            exporter.unexport();
        }
    }

}