using Ion.Sdk.Ddr;
using Ion.Sdk.Ici;
using Ion.Sdk.Idi;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Ion.Sdk.DemoApp.Examples
{
    /// <summary>
    /// Sample demonstrates how upload/download workspace and write/read data from it.
    /// </summary>
    internal static class BlackBox_SingleTest
    {

        private static void Main_BlackBox_SingleTest_Entry(string[] args)
        {
            const string port = "COM10";
            const string blackBoxPassword = "1111";

            try
            {
                var dataRek = Mi3360.BlackBox.StartSingleTest(port, blackBoxPassword);
                dataRek.Wait();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
        }

        public static class Mi3360
        {
            public static class BlackBox
            {
                private static List<string> availableKeys = new List<string>();
                private static List<string> availableActions = new List<string>();

                public static async Task StartSingleTest(string port, string blackBoxPassword)
                {
                    const int measurementId = 147;
                    const string actionStop = "Stop_test";
                    var region = new Region(8000, 2);

                    var measurementInfo = DataDisplayInfos.MeasurementInfoList.First(item => item.Id == measurementId);

                    // subscribe to blackbox messages
                    using (Channel.BlackBox.Get<Channel.BlackBox.Message.AvailableActions>().Subscribe(OnBlackBoxAvailableActions))
                    using (Channel.BlackBox.Get<Channel.BlackBox.Message.AvailableKeys>().Subscribe(OnBlackBoxAvailableKeys))
                    using (Channel.BlackBox.Get<Channel.BlackBox.Message.Error>().Subscribe(OnBlackBoxError))
                    using (Channel.BlackBox.Get<Channel.BlackBox.Message.Notification>().Subscribe(OnBlackBoxNotification))
                    using (Channel.BlackBox.Get<Channel.BlackBox.Message.Question>().Subscribe(OnBlackBoxQuestion))
                    using (var channel = Channel.Serial.Open(port))
                    using (var blackBox = Channel.BlackBox.Create(channel, blackBoxPassword: blackBoxPassword))
                    {
                        var test = new SingleTest(new EmptyMeasurement(measurementInfo.Id, region));
                        var measuredTest = await blackBox.Start(test, blackBox.Stop);
                        blackBox.ExecuteAction(actionStop);
                    }
                }

                private static void OnBlackBoxAvailableKeys(Channel.BlackBox.Message.AvailableKeys message)
                    => availableKeys = message.Keys;

                private static void OnBlackBoxAvailableActions(Channel.BlackBox.Message.AvailableActions message)
                    => availableActions = message.Actions;

                private static void OnBlackBoxError(Channel.BlackBox.Message.Error errorMessage)
                    => Console.WriteLine($"BlackBox Error: #{errorMessage.ErrorNumber}");

                private static void OnBlackBoxNotification(Channel.BlackBox.Message.Notification notification)
                {
                    Console.WriteLine($"BlackBox Notification: {notification.Caption}: {notification.Text}");
                    var response = notification.CreateResponse(BlackBoxMessageButtons.Ok);

                    // send response back
                    Channel.BlackBox.Publish(response);
                }

                private static void OnBlackBoxQuestion(Channel.BlackBox.Message.Question question)
                {
                    Console.WriteLine($"BlackBox Question");

                    var response = question.CreateResponse(BlackBoxMessageButtons.Yes);
                    Channel.BlackBox.Publish(response);
                }
            }
        }
    }
}
