using CommandLine;
using CommandLine.Text;
using System;
using System.Collections.Generic;
using MxLBPLibrary;

namespace mx_lanbypass_ctl_csharp
{
    class Program
    {
        class Options
        {
            [Option('c', Required = true, Default = null,
                HelpText = "-c <Uart Command>\n" +
                "0 --> RelayMode\n" +
                "1 --> WDT Reset Mode\n" +
                "2 --> WDT Relay Mode\n" +
                "3 --> APP WDT Mode\n" +
                "4 --> APP WDT Kick (Send only once)\n" +
                "5 --> APP WDT Reset Mode\n" +
                "6 --> APP WDT Relay Mode\n" +
                "7 --> PowerOff Relay Mode\n" +
                "8 --> Check MCU FW Version")]
            public int Command { get; set; }

            [Option('m', Required = false, Default = -1,
                HelpText = "-m <Mode>\n" +
                "0 --> Connect / Not Reset / Disable\n" +
                "1 --> Disconnect / Reset / Enable\n" +
                "2 --> Bypass")]
            public int Mode { get; set; }

            [Option('t', Required = false, Default = 5, HelpText = "-t <Timeout>")]
            public int Timeout { get; set; }

            [Usage(ApplicationAlias = "mx-lanbypass-ctl_csharp")]
            public static IEnumerable<Example> Examples
            {
                get
                {
                    yield return new Example("Get App WDT Relay Mode", new Options { Command = 6 });
                    yield return new Example("Set WDT Reset Mode to Disconnect", new Options { Command = 1, Mode = 1 });
                    yield return new Example("Set App WDT Mode to Enable and Timeout 5s", new Options { Command = 3, Mode = 1, Timeout = 5 });
                    yield return new Example("Send App WDT Kick", new Options { Command = 4 });
                    yield return new Example("Check MCU Firmware Version", new Options { Command = 8 });
                }
            }
        }

        public static MxLBP _mxLBPLib = new MxLBP(new RealMCU());

        enum Uart_Command
        {
            RELAYMODE = 0,
            WDTRESETMODE = 1,
            WDTRELAYMODE = 2,
            APPWDTMODE = 3,
            APPWDTKICK = 4,
            APPWDTRESETMODE = 5,
            APPWDTRELAYMODE = 6,
            POWEROFFRELAYMODE = 7,
            CHECKMCUFIRMWAREVERSION = 8
        };

        static void ShowLBPMessage(int command, int status, int timeout, string version)
        {
            switch (command)
            {
                default:
                    break;
                case (int)Uart_Command.RELAYMODE:
                    if (status == 0)
                        System.Console.WriteLine("Current Relay Mode is Connect.");
                    else if (status == 1)
                        System.Console.WriteLine("Current Relay Mode is Disconnect.");
                    else
                        System.Console.WriteLine("Current Relay Mode is By Pass.");
                    break;
                case (int)Uart_Command.WDTRESETMODE:
                    if (status == 0)
                        System.Console.WriteLine("Current WDT Reset Mode is Not Reset.");
                    else
                        System.Console.WriteLine("Current WDT Reset Mode is Reset.");
                    break;
                case (int)Uart_Command.WDTRELAYMODE:
                    if (status == 0)
                        System.Console.WriteLine("Current WDT Relay Mode is Connect.");
                    else if (status == 1)
                        System.Console.WriteLine("Current WDT Relay Mode is Disconnect.");
                    else
                        System.Console.WriteLine("Current WDT Relay Mode is By Pass.");
                    break;
                case (int)Uart_Command.APPWDTMODE:
                    if (status == 0)
                        System.Console.WriteLine("Current App WDT Mode is Disable.");
                    else
                    {
                        System.Console.WriteLine("Current App WDT Mode is Enable.");
                        System.Console.WriteLine("Current App WDT Timeout is " + timeout.ToString() + " sec");
                    }
                    break;
                case (int)Uart_Command.APPWDTKICK:
                    System.Console.WriteLine("Send App WDT Kick.\n");
                    break;
                case (int)Uart_Command.APPWDTRESETMODE:
                    if (status == 0)
                        System.Console.WriteLine("Current App WDT Reset Mode is Not Reset.");
                    else
                        System.Console.WriteLine("Current App WDT Reset Mode is Reset.");
                    break;
                case (int)Uart_Command.APPWDTRELAYMODE:
                    if (status == 0)
                        System.Console.WriteLine("Current App WDT Relay Mode is Connect.");
                    else if (status == 1)
                        System.Console.WriteLine("Current App WDT Relay Mode is Disconnect.");
                    else
                        System.Console.WriteLine("Current App WDT Relay Mode is By Pass.");
                    break;
                case (int)Uart_Command.POWEROFFRELAYMODE:
                    if (status == 0)
                        System.Console.WriteLine("Current Power Off Relay Mode is Disconnect.");
                    else
                        System.Console.WriteLine("Current Power Off Relay Mode is By Pass.");
                    break;
                case (int)Uart_Command.CHECKMCUFIRMWAREVERSION:
                    System.Console.WriteLine("MCU Firmware Version is " + version + "\n");
                    break;
            }
        }

        static void ExitProcess(string item)
        {
            Console.WriteLine("[ERROR] " + item);
            Environment.Exit(Environment.ExitCode);
        }
        static void DoAction(int command, int mode, int timeout)
        {
            int ret;
            int status = 0;
            string version = "N\\A";
            switch (command)
            {
                default:
                    ExitProcess("Wrong Command index\n");
                    break;
                case (int)Uart_Command.RELAYMODE:
                    if (mode == -1)
                    {
                        ret = _mxLBPLib.GetRelayMode(out status);
                        if (ret == 1)
                            ExitProcess("Get Relay Mode fail");
                    }
                    else if (mode == 0 || mode == 1 || mode == 2)
                    {
                        ret = _mxLBPLib.SetRelayMode(mode);
                        if (ret == 1)
                            ExitProcess("Set Relay Mode fail");

                        ret = _mxLBPLib.GetRelayMode(out status);
                        if (ret == 1)
                            ExitProcess("Get Relay Mode fail");
                    }
                    else
                        ExitProcess("Mode must be 0:Connect/ 1:Disconnect/ 2:ByPass");
                    break;

                case (int)Uart_Command.WDTRESETMODE:
                    if (mode == -1)
                    {
                        ret = _mxLBPLib.GetWDTResetMode(out status);
                        if (ret == 1)
                            ExitProcess("Get WDT Reset Mode fail");
                    }
                    else if (mode == 0 || mode == 1)
                    {
                        ret = _mxLBPLib.SetWDTResetMode(mode);
                        if (ret == 1)
                            ExitProcess("Set WDT Reset Mode fail");

                        ret = _mxLBPLib.GetWDTResetMode(out status);
                        if (ret == 1)
                            ExitProcess("Get WDT Reset Mode fail");
                    }
                    else
                        ExitProcess("Mode must be 0:Not Reset/ 1:Reset");
                    break;

                case (int)Uart_Command.WDTRELAYMODE:
                    if (mode == -1)
                    {
                        ret = _mxLBPLib.GetWDTRelayMode(out status);
                        if (ret == 1)
                            ExitProcess("Get WDT Relay Mode fail");
                    }
                    else if (mode == 0 || mode == 1 || mode == 2)
                    {
                        ret = _mxLBPLib.SetWDTRelayMode(mode);
                        if (ret == 1)
                            ExitProcess("Set WDT Relay Mode fail");

                        ret = _mxLBPLib.GetWDTRelayMode(out status);
                        if (ret == 1)
                            ExitProcess("Get WDT Relay Mode fail");
                    }
                    else
                        ExitProcess("Mode must be 0:Connect/ 1:Disconnect/ 2:ByPass");
                    break;

                case (int)Uart_Command.APPWDTMODE:
                    if (mode == -1)
                    {
                        ret = _mxLBPLib.GetAppWDTMode(out status, out timeout);
                        if (ret == 1)
                            ExitProcess("Get App WDT Mode fail");
                    }
                    else if (mode == 0 || mode == 1)
                    {
                        ret = _mxLBPLib.SetAppWDTMode(mode, timeout);
                        if (ret == 1)
                            ExitProcess("Set App WDT Mode fail");
                        ret = _mxLBPLib.GetAppWDTMode(out status, out timeout);
                        if (ret == 1)
                            ExitProcess("Get App WDT Mode fail");
                    }
                    else
                        ExitProcess("Mode must be 0:Disable/1:Enable");
                    break;

                case (int)Uart_Command.APPWDTKICK:
                    ret = _mxLBPLib.SendAppWDTKick();
                    if (ret == 1)
                        ExitProcess("Send App WDT Kick fail");
                    break;

                case (int)Uart_Command.APPWDTRESETMODE:
                    if (mode == -1)
                    {
                        ret = _mxLBPLib.GetAppWDTResetMode(out status);
                        if (ret == 1)
                            ExitProcess("Get App WDT Reset Mode fail");
                    }
                    else if (mode == 0 || mode == 1)
                    {
                        ret = _mxLBPLib.SetAppWDTResetMode(mode);
                        if (ret == 1)
                            ExitProcess("Set App WDT Reset Mode fail");

                        ret = _mxLBPLib.GetAppWDTResetMode(out status);
                        if (ret == 1)
                            ExitProcess("Get App WDT Reset Mode fail");
                    }
                    else
                        ExitProcess("Mode must be 0:Not Reset/ 1:Reset");
                    break;

                case (int)Uart_Command.APPWDTRELAYMODE:
                    if (mode == -1)
                    {
                        ret = _mxLBPLib.GetAppWDTRelayMode(out status);
                        if (ret == 1)
                            ExitProcess("Get App WDT Relay Mode fail");
                    }
                    else if (mode == 0 || mode == 1 || mode == 2)
                    {
                        ret = _mxLBPLib.SetAppWDTRelayMode(mode);
                        if (ret == 1)
                            ExitProcess("Set App WDT Relay Mode fail");

                        ret = _mxLBPLib.GetAppWDTRelayMode(out status);
                        if (ret == 1)
                            ExitProcess("Get App WDT Relay Mode fail");
                    }
                    else
                        ExitProcess("Mode must be 0:Connect/ 1:Disconnect/ 2:ByPass");
                    break;
                case (int)Uart_Command.POWEROFFRELAYMODE:
                    if (mode == -1)
                    {
                        ret = _mxLBPLib.GetPowerOffRelayMode(out status);
                        status -= 1;
                        if (ret == 1)
                            ExitProcess("Get Power Off Relay Mode fail");
                    }
                    else if (mode == 2 || mode == 1)
                    {
                        ret = _mxLBPLib.SetPowerOffRelayMode(mode + 1);
                        if (ret == 1)
                            ExitProcess("Set Power Off Relay Mode fail");

                        ret = _mxLBPLib.GetPowerOffRelayMode(out status);
                        status -= 1;
                        if (ret == 1)
                            ExitProcess("Get Power Off Relay Mode fail");
                    }
                    else
                        ExitProcess("Mode must be 0:Disconnect/ 1:ByPass");
                    break;
                case (int)Uart_Command.CHECKMCUFIRMWAREVERSION:
                    ret = _mxLBPLib.GetMCUFirmwareVersion(out version);
                    if (ret == 1)
                        ExitProcess("Get MCU Firmware Version fail");
                    break;
            }
            ShowLBPMessage(command, status, timeout, version);
        }

        static void Main(string[] args)
        {
            CommandLine.Parser.Default.ParseArguments<Options>(args)
               .WithParsed(opts =>
               {
                   if (opts.Command >= 0 && opts.Command <= 8)
                   {
                       DoAction(opts.Command, opts.Mode, opts.Timeout);
                   }
                   else
                   {
                       Console.WriteLine("[ERROR] Wrong action!\n");
                   }
               });
        }
    }
}
