using System;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;

namespace SWModules
{
public class WatchDog
    {
        private static Thread watchDogThread = new Thread(WatchDog.watchDogHandler);

        private static bool watchDogStarted = false;

        private static int wdTimeout = 15000;

        public static void startWatchdog()
        {
            if (!watchDogStarted)
            {
                GHI.Processor.Watchdog.Enable(wdTimeout);
                watchDogThread = new Thread(watchDogHandler);
                watchDogStarted = true;
                watchDogThread.Start();
            }
        }

        private static TimeSpan lastCycleTime = new TimeSpan();
        [MethodImpl(MethodImplOptions.Synchronized)]
        public static void setLastCycleTime()
        {
            lastCycleTime = Microsoft.SPOT.Hardware.Utility.GetMachineTime(); ;
        }

        private static TimeSpan mainThreadWDTimeout = new TimeSpan(0, 0, 30);
        private static StringBuilder sbTemp = new StringBuilder(128);
        public static void watchDogHandler()
        {
            while (true)
            {
                sbTemp.Clear();
                sbTemp.Append("Watchdog Thread ");
                sbTemp.Append(DateTime.Now.ToString());
                sbTemp.Append(" Watch dog handler main thread last cycle time = ");
                sbTemp.Append(lastCycleTime.ToString());
                //Debug.Print(sbTemp.ToString());

                if ((Microsoft.SPOT.Hardware.Utility.GetMachineTime() - lastCycleTime) > mainThreadWDTimeout)
                {
                    sbTemp.Clear();
                    sbTemp.Append("Watchdog Thread ");
                    sbTemp.Append(DateTime.Now.ToString());
                    sbTemp.Append(" Main thread timout occurred");
                    //Debug.Print(sbTemp.ToString());
                }
                else
                {
                    GHI.Processor.Watchdog.ResetCounter();
                    sbTemp.Clear();
                    sbTemp.Append("Watchdog Thread ");
                    sbTemp.Append(DateTime.Now.ToString());
                    sbTemp.Append(" Reset the watchDog");
                    //Debug.Print(sbTemp.ToString());
                }

                Thread.Sleep(10000);
            }
        }
    }
}
