using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

using ParticulateSensorRecords;

// Allias
using TestedClass = ParticulateSensorRecords.Form1;
using System.Diagnostics;
using System.Collections.Generic;

namespace ParticulateSensorRecordsTest
{
    [TestClass]
    public class TestFixture_ParticulateSensorRecords
    {
        public IFileReader IOhandler;
        private TestedClass Form1;
        private ConfigData configData;
        private LocationList locationList;
        private Location location;
        private AirData airData;
        const string FILENAME = "Test.xml";

        [TestInitialize]
        public void TestInitialize()
        {
            Form1 = new TestedClass(IOhandler);
            configData = new ConfigData();
            locationList = new LocationList();
            location = new Location();
            airData = new AirData();


        locationList = new LocationList();
        }

        [TestCleanup]
        public void TestCleanup()
        {
            Form1 = null;
            configData = null;
            locationList = null;
            location = null;
            airData = null;

        }

        // Test add file to config data
        [TestMethod]
        public void ConfigDataTest()
        {
            string sLoadedString = null;

            // Make sure configData is a new empty object
            configData = new ConfigData();

            // Generate configuration data (filename required for each location)
            configData.configRecords.Add(new ConfigRecord(FILENAME));

            // Read all config records from list
            foreach (var ls in configData.configRecords)
            {
                sLoadedString = ls.ToString();
            }

            string sExceptedString = FILENAME;

            // Assert to check strings
            var failMessage = String.Format(@"Loaded string not same as expected string!");
            Assert.AreEqual(sLoadedString, sExceptedString, failMessage);

            // test how many configdata added
            int iActulListCount = configData.configRecords.Count;

            // Expected number of item in list
            int iExpectedListCount = 1;

            // Assert to check list count
            var failMessage2 = String.Format(@"List items counter doesn't match with expected counter!");
            Assert.AreEqual(iActulListCount, iExpectedListCount, failMessage2);
        }


        // Compare added object and a sample object
        [TestMethod]
        public void CompareAddedAndSampleObjectTest()
        {
            // Create an expected location list            

            // Create a AirData object
            AirData airData = new AirData(Convert.ToDateTime("18/02/2019"), 10, 14.5, 51.5);

            // Create a location
            Location location = new Location("Quayside");

            // Add air data to location's airdata list
            location.AirDatas.Add(airData);

            // Create a location list
            LocationList lExpectedLocationList = new LocationList();

            // Add location to location list
            lExpectedLocationList.Locations.Add(location);

            Location lActual = new Location();
            AirData aActual = new AirData();

            // Loop trough location list
            foreach (var l in lExpectedLocationList)
            {
                lActual = l;
                aActual = l.AirDatas.FirstOrDefault();
            }

            // Check all properties of expected and actual location and air data
            var failMessage = String.Format(@"Actual object doesn't match with expected object!");
            Assert.AreEqual(location.Name, lActual.Name, failMessage);
            Assert.AreEqual(airData.Date, aActual.Date, failMessage);
            Assert.AreEqual(airData.Particulate, aActual.Particulate, failMessage);
            Assert.AreEqual(airData.Huminity, aActual.Huminity, failMessage);
            Assert.AreEqual(airData.Temperature, aActual.Temperature, failMessage);
        }


        // Test Total Particulate calculation
        [TestMethod]
        public void TotalParticulateCalculationTest()
        {
            // Create an expected location list

            // Create a AirData objects            
            AirData airData1 = new AirData(Convert.ToDateTime("18/02/2019"), 13, 8.0, 51.5);
            AirData airData2 = new AirData(Convert.ToDateTime("19/02/2019"), 21, 11.4, 55.0);
            AirData airData3 = new AirData(Convert.ToDateTime("18/02/2019"), 12, 10.6, 52.3);
            AirData airData4 = new AirData(Convert.ToDateTime("19/02/2019"), 24, 9.3, 53.9);

            // Create a locations
            Location location1 = new Location("Quayside");
            Location location2 = new Location("Rokker");

            // Add air data to location's airdata list
            location1.AirDatas.Add(airData1);
            location1.AirDatas.Add(airData2);

            location2.AirDatas.Add(airData3);
            location2.AirDatas.Add(airData4);

            // Create a location list
            LocationList lExpectedLocationList = new LocationList();

            // Add location to location list
            lExpectedLocationList.Locations.Add(location1);
            lExpectedLocationList.Locations.Add(location2);

            // List to send data
            List<String> locationParticulateList = new List<string>();

            // Get back the calculation
            locationParticulateList = lExpectedLocationList.CalculateLocationTotal();

            // List to get data back
            List<String> actualParticulateList = new List<string>();

            for (int i = 0; i < locationParticulateList.Count; i++)
            {
                actualParticulateList.Add(locationParticulateList[i]);
            }

            // Expected totals (higher return back fist), total particulate must 45 (21+24) and 25 (13+12)
            string sExpectedTotal0 = "Date: 19/02/2019, Particulate: 45";
            string sExpectedTotal1 = "Date: 18/02/2019, Particulate: 25";
            

            // Check all properties of expected and actual location and air data
            var failMessage = String.Format(@"Actual object doesn't match with expected object!");
            Assert.AreEqual(sExpectedTotal0, locationParticulateList[0], failMessage);
            Assert.AreEqual(sExpectedTotal1, locationParticulateList[1], failMessage);
        }
    }
}
