// **********************************************************************
//
// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************

using System;
using System.Collections.Generic;

public class Instrumentation
{
    static Object mutex = new Object();

    class InvocationObserverI : Ice.Instrumentation.InvocationObserver
    {
        public void 
        attach()
        {
        }
        
        public void 
        detach()
        {
            lock(mutex)
            {
                ++nInvocation;
            }
        }

        public void 
        failed(string msg)
        {
            lock(mutex)
            {
                ++nFailure;
            }
        }

        public void 
        retried()
        {
            lock(mutex)
            {
                ++nRetry;
            }
        }

        public void 
        userException()
        {
        }
        
        public Ice.Instrumentation.RemoteObserver
        getRemoteObserver(Ice.ConnectionInfo ci, Ice.Endpoint ei, int i, int j)
        {
            return null;
        }

        public Ice.Instrumentation.CollocatedObserver 
        getCollocatedObserver(Ice.ObjectAdapter adapter, int i , int j)
        {
            return null;
        }

    };
    static private Ice.Instrumentation.InvocationObserver invocationObserver = new InvocationObserverI();

    class CommunicatorObserverI : Ice.Instrumentation.CommunicatorObserver
    {
        public Ice.Instrumentation.Observer 
        getConnectionEstablishmentObserver(Ice.Endpoint e, string s)
        {
            return null;
        }

        public Ice.Instrumentation.Observer 
        getEndpointLookupObserver(Ice.Endpoint e)
        {
            return null;
        }

        public Ice.Instrumentation.ConnectionObserver 
        getConnectionObserver(Ice.ConnectionInfo ci, 
                              Ice.Endpoint ei, 
                              Ice.Instrumentation.ConnectionState s,
                              Ice.Instrumentation.ConnectionObserver o)
        {
            return null;
        }
        
        public Ice.Instrumentation.ThreadObserver 
        getThreadObserver(string p, 
                          string n, 
                          Ice.Instrumentation.ThreadState s, 
                          Ice.Instrumentation.ThreadObserver o)
        {
            return null;
        }

        public Ice.Instrumentation.InvocationObserver 
        getInvocationObserver(Ice.ObjectPrx p, string o, Dictionary<string, string> c)
        {
            return invocationObserver;
        }
        
        public Ice.Instrumentation.DispatchObserver 
        getDispatchObserver(Ice.Current c, int i)
        {
            return null;
        }
        
        public void 
        setObserverUpdater(Ice.Instrumentation.ObserverUpdater u)
        {
        }
    };
    
    static private Ice.Instrumentation.CommunicatorObserver communicatorObserver = new CommunicatorObserverI();

    static public Ice.Instrumentation.CommunicatorObserver
    getObserver()
    {
        return communicatorObserver;
    }
    
    static private void
    testEqual(ref int value, int expected)
    {
        if(expected < 0)
        {
            value = 0;
            return;
        }

        int retry = 0;
        while(++retry < 100)
        {
            lock(mutex)
            {
                if(value == expected)
                {
                    break;
                }
            }
            System.Threading.Thread.Sleep(10);
        }
        if(value != expected)
        {
            System.Console.Error.WriteLine("value = " + value + ", expected = " + expected);
            System.Diagnostics.Debug.Assert(false);
            throw new System.Exception();
        }
        value = 0;
    }
    
    static public void
    testRetryCount(int expected)
    {
        testEqual(ref nRetry, expected);
    }

    static public void
    testFailureCount(int expected)
    {
        testEqual(ref nFailure, expected);
    }

    static public void
    testInvocationCount(int expected)
    {
        testEqual(ref nInvocation, expected);
    }

    static private int nRetry = 0; 
    static private int nFailure = 0;
    static private int nInvocation = 0;
};
