using System.Text;
using System.Threading;
using HWModules;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SWModules;

namespace CPFUnitTests.PowerSwitchBoard
{
    /// <summary>
    /// This Unit Test was written to test the SN1 configuration 
    /// as manufactured in Fall 2017. The configuration is an all
    /// native UART board for RS232 channels. Energy monitors will
    /// be tested but may not be used. 
    /// 
    /// Some tests that don't require external wiring will just
    /// occur, and others will prompt through the debugging 
    /// console for the opertor to press the LDR0 button on the
    /// motherboard. 
    /// 
    /// -EJM
    /// </summary>
    [TestClass]
    public class UnitTest_PSB_SN3
    {
        private HWModules.MotherBoard mb;
        private bool _runonce = false;
        private void Init()
        {
            if (!_runonce)
            {
                mb = HWModules.MotherBoard.Instance;
                _runonce = true;
            }

        }

        private void WaitForLdr0()
        {
            Debug.Print("Press LDR0 Button to Continue... \n");
            while (!mb.Ldr0Pushed)
                Thread.Sleep(100);
            //Clear the state
            mb.Ldr0Pushed = false;
        }


        [TestMethod]
        public void TestEnergyMonitorAndPowerSlot3A()
        {
            Init();

            mb.Enable12V();
            mb.Enable5V();
            mb.EnableChannelPower(7);

            Debug.Print("\n\nEM Slot3A TEST");
            WaitForLdr0();
            
            EnergyMonitorLTC2946 em = new EnergyMonitorLTC2946(new I2CDevice.Configuration(0xCE >> 1, 400), EnergyMonitorLTC2946.VoltageSource.Adin, 0.005865, 0.625,3);
            em.ReadCtlARegister();

            for (int i=0; i<10; i++)
            {
                EnergyMonitorLTC2946.EM_VandI data = em.getVandI();
                Debug.Print("SLOT3A DATA V/I:" + data.volts.ToString() + " / " + data.amps.ToString());
                Thread.Sleep(100);
            }

            Debug.Print("Please Attempt to overload the circuit (>2.5A)");
            WaitForLdr0();

            mb.DisableChannelPower(7);
            mb.Disable12V();
            mb.Disable5V();
        }

        [TestMethod]
        public void TestEnergyMonitorAndPowerSlot3B()
        {
            Init();

            mb.Enable12V();
            mb.Enable5V();
            mb.EnableChannelPower(8);
            
            Debug.Print("\n\nEM Slot3B TEST");
            WaitForLdr0();

            EnergyMonitorLTC2946 em = new EnergyMonitorLTC2946(new I2CDevice.Configuration(0xD2 >> 1, 400), EnergyMonitorLTC2946.VoltageSource.Adin, 0.005865, 0.625,3);
            em.ReadCtlARegister();
            
            for (int i=0; i<10; i++)
            {
                EnergyMonitorLTC2946.EM_VandI data = em.getVandI();
                Debug.Print("SLOT3B DATA V/I:" + data.volts.ToString() + " / " + data.amps.ToString());
                Thread.Sleep(100);
            }

            Debug.Print("Please Attempt to overload the circuit (>1.25A)");
            WaitForLdr0();

            mb.DisableChannelPower(8);
            mb.Disable12V();
            mb.Disable5V();
        }

        [TestMethod]
        public void TestEnergyMonitorAndPowerSlot3C()
        {
            Init();

            mb.Enable12V();
            mb.Enable5V();
            mb.EnableChannelPower(9);
            
            Debug.Print("\n\nEM Slot3C TEST");
            WaitForLdr0();

            EnergyMonitorLTC2946 em = new EnergyMonitorLTC2946(new I2CDevice.Configuration(0xD8 >> 1, 400), EnergyMonitorLTC2946.VoltageSource.Adin, 0.005865, 0.625, 3);
            em.ReadCtlARegister();

            for (int i=0; i<10; i++)
            {
                EnergyMonitorLTC2946.EM_VandI data = em.getVandI();
                Debug.Print("SLOT3C DATA V/I:" + data.volts.ToString() + " / " + data.amps.ToString());
                Thread.Sleep(100);
            }

            Debug.Print("Please Attempt to overload the circuit (>1.25A)");
            WaitForLdr0();

            mb.DisableChannelPower(9);
            mb.Disable12V();
            mb.Disable5V();
        }

        [TestMethod]
        public void TestI2CSerialPortSlot3A()
        {
            Debug.Print("\nI2C UART Slot3A Test // Connect to J3\n");
            Init();
            WaitForLdr0();

            mb.Enable12V();mb.Enable5V();
            mb.EnableChannelPower(7);

            var port = new I2CSerialPort("COM7", 19200);
            port.DataReceived += port_DataReceived;
            port.Open();

            var msgBytes = Encoding.UTF8.GetBytes("Hello Port 3A\r\n");

            Debug.Print("Transmitting message on port, please type a message back.");

            for (int i=0; i < 10; i++) {
                port.Write(msgBytes, 0, msgBytes.Length);
                Thread.Sleep(1000);
            }
            WaitForLdr0();
            port.Close();
            mb.DisableChannelPower(9);
            mb.Disable12V();
            mb.Disable5V();

        }

        [TestMethod]
        public void TestI2CSerialPortSlot3B()
        {
            Init();
            Debug.Print("\nI2C UART Slot3B Test // Connect to J4\n");
            //WaitForLdr0();

            var port = new I2CSerialPort("COM8", 19200
            );
            port.DataReceived += port_DataReceived;
            port.Open();
            Thread.Sleep(1000);

            mb.Enable12V(); 
            mb.Enable5V();

            Thread.Sleep(1000);
            Debug.Print("Disabling channel 8 power;");
            mb.DisableChannelPower(8);

            Thread.Sleep(2000);
            Debug.Print("Enabling channel 8 power;");
            mb.EnableChannelPower(8);

            var msgBytes = Encoding.UTF8.GetBytes("Hello Port 3B\r\n");

            Debug.Print("Transmitting message on port, please type a message back.");

            for (int i = 0; i < 10; i++)
            {
                port.Write(msgBytes, 0, msgBytes.Length);
                Thread.Sleep(1000);
            }

            WaitForLdr0();
            port.Close();
            mb.DisableChannelPower(8);
            mb.Disable12V();
            mb.Disable5V();

        }

        [TestMethod]
        public void TestI2CSerialPortSlot3C()
        {
            Debug.Print("\nI2C UART Slot3C Test // Connect to J5\n");
            Init();
            WaitForLdr0();

            mb.Enable12V();mb.Enable5V();
            mb.EnableChannelPower(9);

            var port = new I2CSerialPort("COM9", 19200);
            port.DataReceived += port_DataReceived;
            port.Open();

            var msgBytes = Encoding.UTF8.GetBytes("Hello Port 3c\r\n");

            Debug.Print("Transmitting message on port, please type a message back.");

            for (int i=0; i < 10; i++) {
                port.Write(msgBytes, 0, msgBytes.Length);
                Thread.Sleep(1000);
            }
            WaitForLdr0();
            port.Close();
            mb.DisableChannelPower(9);
            mb.Disable12V();
            mb.Disable5V();

        }

        private StringBuilder _sbTemp = new StringBuilder();
        private void port_DataReceived(object sender, EventArgs e)
        {
            var inbuff = new byte[1024];

            var port = (I2CSerialPort) sender;
            port.Read(inbuff, 0, port.BytesToRead);
            _sbTemp.Append(SafeEncoding.GetChars(inbuff));
            Debug.Print("Got Line: " + _sbTemp.ToString());

        }
    
    }
}
