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_AutoSequence
    {

        private static async Task Main(string[] args)
        {
            const string port = "COM5";
            const string blackBoxPassword = "password123";
            const string autoSequenceName = "MI3360 Autosequence_AutoSave";

            try
            {
                await Mi3360.BlackBox.StartAutoSequence(autoSequenceName, port, blackBoxPassword);
            }
            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 StartAutoSequence(string autoSequenceName, string port, string blackBoxPassword)
                {
                    const int measurementId = 80;
                    var region = new Region(2000, 1);

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

                    // subscribe to blackbox messages
                    using (Channel.BlackBox.Get<Channel.BlackBox.Message.AvailableActions>().Subscribe(message => availableActions = message.Actions))
                    using (Channel.BlackBox.Get<Channel.BlackBox.Message.AvailableKeys>().Subscribe(message => availableKeys = message.Keys))
                    using (Channel.BlackBox.Get<Channel.BlackBox.Message.Error>().Subscribe(message => Console.WriteLine($"BlackBox Error: #{message.ErrorNumber}")))
                    using (Channel.BlackBox.Get<Channel.BlackBox.Message.Notification>().Subscribe(OnBlackBoxNotification))
                    using (Channel.BlackBox.Get<Channel.BlackBox.Message.Question>().Subscribe(OnBlackBoxQuestion))
                    using (Channel.BlackBox.Get<Channel.BlackBox.Message.Keyboard>().Subscribe(OnBlackBoxKeyboard))
                    using (Channel.BlackBox.Get<Channel.BlackBox.Message.AutoSequenceStepEndDecision>().Subscribe(OnBlackBoxStepEndDecision))
                    using (var channel = Channel.Serial.Open(port))
                    using (var blackBox = Channel.BlackBox.Create(channel, blackBoxPassword: blackBoxPassword))
                    {
                        var result = await blackBox.StartAutoSequence(autoSequenceName, region, false);

                        Console.WriteLine("Press any key...");
                        blackBox.ExecuteAction(Ici.BlackBox.Predefined.Actions.StopTest);
                    }
                }

                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);
                }

                private static void OnBlackBoxKeyboard(Channel.BlackBox.Message.Keyboard message)
                {
                    if (message.Type == BlackBoxMessageTextTypes.Alphanumeric)
                        Channel.BlackBox.Publish(message.CreateResponse("abc"));
                    else
                        Channel.BlackBox.Publish(message.CreateResponse("123"));
                }

                private static void OnBlackBoxStepEndDecision(Channel.BlackBox.Message.AutoSequenceStepEndDecision message)
                {
                    message.Channel.ExecuteAction("End");
                }
            }
        }
    }
}
