using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Xml;
using GHI.IO.Storage;
using HWModules;
using Microsoft.SPOT;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace CPFUnitTests.Core
{

    [TestClass]
    class MissionConfigUT
    {
        [TestMethod]
        public void TestStringParse()
        {
            byte[] xml = UTF8Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
                "<config>\r\n" +
                "    <item key=\"platformName\" value=\"cpf003\" />\r\n" +
                "    <item key=\"logVerbosity\" value=\"4\" />\r\n" +
                "    <item key=\"debugVerbosity\" value=\"4\" />\r\n" +
                "    <item key=\"systemDataSamplePeriod\" value=\"30\" />\r\n" +
                "    <item key=\"preMissionDelayPeriod\" value=\"30\" />\r\n" +
                "    <!--buoyancy control-->\r\n" +
                "    <item key=\"stringPotDirection\" value=\"down\" />\r\n" +
                "    <item key=\"bellowsLowerLimit\" value=\"85.0\" />\r\n" +
                "    <item key=\"bellowsUpperLimit\" value=\"250.0\" />\r\n" +
                "    <item key=\"surfaceOpsSetBellowsPostiion\" value=\"155.0\" />\r\n" +
                "    <item key=\"surfaceOpsSetBellowsJogVelocity\" value=\"200000\" />\r\n" +
                "    <item key=\"recoveryModeSetBellowsPosition\" value=\"105.0\" />\r\n" +
                "    <item key=\"abRetractFastJogVelocity\" value=\"200000\" />\r\n" +
                "    <item key=\"abRetractSlowJogVelocity\" value=\"200000\" />\r\n" +
                "    <item key=\"abPressureThreshold\" value=\"0.3\" />\r\n" +
                "    <!--anchoring-->\r\n" +
                "    <item key=\"deanchorVelocityThreshold\" value=\"0.007\" />\r\n" +
                "    <item key=\"deanchorJogVelocity\" value=\"200000\" />\r\n" +
                "    <item key=\"deanchorVelocityLimit\" value=\"0.02\" />\r\n" +
                "    <item key=\"anchorPressureCountThreshold\" value=\"3\" />\r\n" +
                "    <item key=\"anchorPressureMinimum\" value=\"4.0\" />\r\n" +
                "    <item key=\"anchorVelocityLimit\" value=\"0.025\" />\r\n" +
                "    <item key=\"exitAnchorPressureThreshold\" value=\"5.0\" />\r\n" +
                "    <item key=\"approachVelocity\" value=\"0.01\" />\r\n" +
                "    <!--SBE41 CTD-->\r\n" +
                "    <item key=\"cpPressureCutoff\" value=\"1\" />\r\n" +
                "    <item key=\"cpRunPumpTime\" value=\"2\" />\r\n" +
                "    <item key=\"cpMode\" value=\"1\" />\r\n" +
                "    <item key=\"sbe41CommandModeSamplePeriod\" value=\"3000\" />\r\n" +
                "    <item key=\"sbe41CpSamplePeriod\" value=\"1000\" />\r\n" +
                "</config>\r\n");

            var stream = new MemoryStream(xml);

            using (XmlReader reader = XmlReader.Create(stream)) {
                bool loop = true;
                while (loop) {
                    try {
                        loop = reader.Read();
                        Debug.Print(reader.Name);
                    }
                    catch (Exception e) {
                        Debug.Print(e.ToString());
                    }
                }

            }

        }

        [TestMethod]
        public void TestStringParseWithAttributes()
        {
            byte[] xml = UTF8Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"+
                "<cpf>\r\n"+
"<item key=\"name\" value=\"cpf003\"/>\r\n" +
"<item key=\"engrLogVerb\" value=\"4\"/>\r\n"+
"<item key=\"debugLogVerb\" value=\"4\"/>\r\n"+
"<item key=\"sysDataSampPeriod\" value=\"30\"/>\r\n"+
"<item key=\"preMissDelayPeriod\" value=\"30\"/>\r\n"+
"<item key=\"stringPotDir\" value=\"1\"/>\r\n"+
"<item key=\"bellowsLower\" value=\"2\"/>\r\n"+
"<item key=\"bellowsUpper\" value=\"98\"/>\r\n"+
"<item key=\"soBellowsPos\" value=\"75\"/>\r\n"+
"<item key=\"soBellowsJV\" value=\"200000\"/>\r\n"+
"<item key=\"rmBellowsPos\" value=\"50\"/>\r\n"+
"<item key=\"abRetFastJV\" value=\"200000\"/>\r\n"+
"<item key=\"abRetSlowJV\" value=\"200000\"/>\r\n"+
"<item key=\"abPressThres\" value=\"0.3\"/>\r\n"+
"<item key=\"deAnchorVelLim\" value=\"0.007\"/>\r\n"+
"<item key=\"deAnchorJV\" value=\"200000\"/>\r\n"+
"<item key=\"deAnchorVelocityLimit\" value=\"0.025\"/>\r\n"+
"<item key=\"deAnchorPressMin\" value=\"5\"/>\r\n"+
"<item key=\"anchorCount\" value=\"3\"/>\r\n" +
"<item key=\"anchorPressMin\" value=\"4\"/>\r\n"+
"<item key=\"anchorVelLim\" value=\"0.025\"/>\r\n"+
"<item key=\"exitAnchorPressThres\" value=\"5.0\"/>\r\n"+
"<item key=\"approachVel\" value=\"0.01\"/>\r\n"+
"<item key=\"cpPressCutoff\" value=\"1\"/>\r\n"+
"<item key=\"cpRunPumpTime\" value=\"2\"/>\r\n"+
"<item key=\"cpMode\" value=\"1\"/>\r\n"+
"<item key=\"sbeComSampPeriod\" value=\"3000\"/>\r\n"+
"<item key=\"sbeCpSamplePeriod\" value=\"1000\"/>\r\n</cpf>\r\n");

            var stream = new MemoryStream(xml);

            using (XmlReader reader = XmlReader.Create(stream)) {
                bool loop = true;
                while (loop) {
                    try {
                        loop = reader.Read();
                        Debug.Print(reader.Name);

                        switch (reader.Name) {
                            case "item":
                                var key = reader.GetAttribute("key");
                                var value = reader.GetAttribute("value");
                                Debug.Print("Key: " + key + "\t Value: " + value);
                                break;

                        }
                    }
                    catch (Exception e) {
                        Debug.Print(e.ToString());
                    }
                }

            }

        }


        [TestMethod]
        public void TestFileParseWithAttributes()
        {
            var sd = SDStorage.Instance;

            var file = @"\SD\config\cpf.xml";
            var stream = new FileStream(file, FileMode.Open);

            using (XmlReader reader = XmlReader.Create(stream)) {
                bool loop = true;
                while (loop) {
                    try {
                        loop = reader.Read();
                        Debug.Print(reader.Name);

                        switch (reader.Name) {
                            case "item":
                                var key = reader.GetAttribute("key").ToLower();
                                var value = reader.GetAttribute("value");
                                Debug.Print("Key: " + key + "\t Value: " + value);
                                break;

                        }
                    }
                    catch (Exception e) {
                        Debug.Print(e.ToString());
                    }
                }

            }

        }

        [TestMethod]
        public void TestFileParseToMissionConfig()
        {
            var sd = SDStorage.Instance;

            var file = @"\SD\config\cpf.xml";
            var stream = new FileStream(file, FileMode.Open);

            using (XmlReader reader = XmlReader.Create(stream)) {
                bool loop = true;
                while (loop) {
                    try {
                        loop = reader.Read();
                        Debug.Print(reader.Name);

                        if (reader.Name != "item")
                            continue;

                        string key;
                        string value = reader.GetAttribute("value");

                        try {
                            switch (key = reader.GetAttribute("key").ToLower()) {
                                case "name":
                                    MissionConfig.PlatformName = value;
                                    break;
                                case "engrlogverb":
                                    MissionConfig.EngrLoggerVerbosityLevel = int.Parse(value);
                                    break;
                                case "debuglogverb":
                                    MissionConfig.DebuggerVerbosityLevel = int.Parse(value);
                                    break;
                                case "sysdatasampperiod":
                                    MissionConfig.SetSystemDataSamplePeriod(int.Parse(value));
                                    break;
                                case "premissdelayperiod":
                                    MissionConfig.SetPreMissionDelayPeriod(int.Parse(value));
                                    break;
                                case "bellowslower":
                                    MissionConfig.IBFillLowerLimit = double.Parse(value);
                                    break;
                                case "bellowsupper":
                                    MissionConfig.IBFillLowerLimit = double.Parse(value);
                                    break;
                                case "sobellowspos":
                                    MissionConfig.SOSetBellowsPosition = double.Parse(value);
                                    break;
                                case "sobellowsjv":
                                    MissionConfig.SOSetBellowsJV = int.Parse(value);
                                    break;
                                case "rmbellowspos":
                                    MissionConfig.RMSetBellowsPosition = double.Parse(value);
                                    break;
                                case "abretfastjv":
                                    MissionConfig.ABRetractFastJV = int.Parse(value);
                                    break;
                                case "abretslowjv":
                                    MissionConfig.ABRetractSlowJV = int.Parse(value);
                                    break;
                                case "abpressthres":
                                    MissionConfig.ABPressureThreshold = double.Parse(value);
                                    break;
                                case "deanchorpresmin":
                                    MissionConfig.DeanchorPressureMinimum = double.Parse(value);
                                    break;
                                case "deanchorcountthres":
                                    MissionConfig.DeanchorPressureCountThreshold = int.Parse(value);
                                    break;
                                case "deanchorjv":
                                    MissionConfig.DeanchorJV = int.Parse(value);
                                    break;
                                case "deanchorvellim":
                                    MissionConfig.DeanchorVelocityLimit = double.Parse(value);
                                    break;
                                case "deanchorpressmin":
                                    MissionConfig.DeanchorPressureMinimum = double.Parse(value);
                                    break;
                                case "deanchorcount":
                                    MissionConfig.DeanchorPressureCountThreshold = int.Parse(value);
                                    break;
                                case "anchorcount":
                                    MissionConfig.AnchorPressureCountThreshold = int.Parse(value);
                                    break;
                                case "anchorpressmin":
                                    MissionConfig.AnchorPressureMinimum = double.Parse(value);
                                    break;
                                case "anchorvellim":
                                    MissionConfig.AnchorVelocityLimit = double.Parse(value);
                                    break;
                                case "exitanchorpressthres":
                                    MissionConfig.ExitAnchorPressureThreshold = double.Parse(value);
                                    break;
                                case "approachvel":
                                    MissionConfig.ApproachVelocity = double.Parse(value);
                                    break;
                                case "cppresscutoff":
                                    MissionConfig.CpPressureCutoff = int.Parse(value);
                                    break;
                                case "cprunpumptime":
                                    MissionConfig.CpRunPumpTime = int.Parse(value);
                                    break;
                                case "cpmode":
                                    MissionConfig.CPMode = int.Parse(value) == 1;
                                    break;
                                case "sbecomsampperiod":
                                    MissionConfig.SBE41CPSamplePeriod = int.Parse(value);
                                    break;
                                case "sbecpsampperiod":
                                    MissionConfig.SBE41CPSamplePeriod = int.Parse(value);
                                    break;
                                case "stringpotinverseslope":
                                    MissionConfig.StringPotInverseSlope = int.Parse(value);
                                    break;
                                case "stringpotint":
                                    MissionConfig.StringPotIntercept = double.Parse(value);
                                    break;
                                default:
                                    throw new ArgumentException("Unknown item present in xml file: " + key);
                                    break;
                            }
                        }
                        catch (Exception err) {
                            EngrLogger.Comment(err.ToString());
                        }

                    }
                    catch (Exception e) {
                        Debug.Print(e.ToString());
                    }
                }

            }

        }

        [TestMethod]
        public void TestFileParseUsingMethod()
        {


            var file = @"\SD\config\cpf.xml";
            MissionConfig.LoadConfig(file);
            Debug.Print(MissionConfig.ToString());
        }
    }
}
