//-----------------------------------------------------------------------
// 
//     Copyright (c) Microsoft Corporation.
// 
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
    using System;
    using System.Diagnostics;
    using Microsoft.Isam.Esent.Interop.Vista;
    /// 
    /// Provides a set of methods and properties that you can use to measure
    /// ESENT work statistics for a thread. If the current version of ESENT
    /// doesn't support  then all 
    /// ESENT statistics will be 0.
    /// 
    public class EsentStopwatch
    {
        /// 
        /// Used to measure how long statistics are collected for.
        /// 
        private Stopwatch stopwatch;
        /// 
        /// The stats at the start of our collection.
        /// 
        private JET_THREADSTATS statsAtStart;
        /// 
        /// Gets a value indicating whether the EsentStopwatch timer is running. 
        /// 
        public bool IsRunning { get; private set; }
        /// 
        /// Gets the total ESENT work stats measured by the current instance.
        /// 
        public JET_THREADSTATS ThreadStats { get; private set; }
        /// 
        /// Gets the total elapsed time measured by the current instance.
        /// 
        public TimeSpan Elapsed { get; private set; }
        /// 
        /// Initializes a new EsentStopwatch instance and starts
        /// measuring elapsed time. 
        /// 
        /// A new, running EsentStopwatch.
        public static EsentStopwatch StartNew()
        {
            var stopwatch = new EsentStopwatch();
            stopwatch.Start();
            return stopwatch;
        }
        /// 
        /// Returns a  that represents the current .
        /// 
        /// 
        /// A  that represents the current .
        /// 
        public override string ToString()
        {
            return this.IsRunning ? "EsentStopwatch (running)" : this.Elapsed.ToString();
        }
        /// 
        /// Starts measuring ESENT work.
        /// 
        public void Start()
        {
            this.Reset();
            this.stopwatch = Stopwatch.StartNew();
            this.IsRunning = true;
            if (EsentVersion.SupportsVistaFeatures)
            {
                VistaApi.JetGetThreadStats(out this.statsAtStart);
            }
        }
        /// 
        /// Stops measuring ESENT work.
        /// 
        public void Stop()
        {
            if (this.IsRunning)
            {
                this.IsRunning = false;
                this.stopwatch.Stop();
                this.Elapsed = this.stopwatch.Elapsed;
                if (EsentVersion.SupportsVistaFeatures)
                {
                    JET_THREADSTATS statsAtEnd;
                    VistaApi.JetGetThreadStats(out statsAtEnd);
                    this.ThreadStats = statsAtEnd - this.statsAtStart;
                }
            }
        }
        /// 
        /// Stops time interval measurement and resets the thread statistics.
        /// 
        public void Reset()
        {
            this.stopwatch = null;
            this.ThreadStats = new JET_THREADSTATS();
            this.Elapsed = TimeSpan.Zero;
            this.IsRunning = false;
        }
    }
}