using CommandLine;
using CommandLine.Text;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace mx_5Gpower_ctl
{
    class Program
    {
        class Options
        {
            [Option('s', Required = true, HelpText = "-s <#M.2B socket index> (Start from 1)")]
            public int SocketIndex { get; set; }

            [Option('p', Default = null, Required = false,
                HelpText = "-p <Power status>\n" +
                "       1 --> power on\n" +
                "       0 --> power off"
                )]
            public int? PowerStatus { get; set; }

            [Option('r', Default = null, Required = false, HelpText = "Set 5G module hardware reset")]
            public bool ModuleReset { get; set; }

            [Usage(ApplicationAlias = "mx-5Gpower-ctl")]
            public static IEnumerable<Example> Examples
            {
                get
                {
                    yield return new Example("Get M.2B socket 1 5G module power status", new Options { SocketIndex = 1 });
                    yield return new Example("Set M.2B socket 1 5G module power on", new Options { SocketIndex = 1, PowerStatus = 1 });
                    yield return new Example("Reset M.2B socket 1 5G module", new Options { SocketIndex = 1, ModuleReset = true });
                }
            }
        }

        [DllImport("mx5Gpower.dll", EntryPoint = "GetPowerStatus", CharSet = CharSet.Ansi, SetLastError = true)]
        public static extern int GetPowerStatus(int port);

        [DllImport("mx5Gpower.dll", EntryPoint = "SetPowerStatus", CharSet = CharSet.Ansi, SetLastError = true)]
        public static extern int SetPowerStatus(int port, int status);

        [DllImport("mx5Gpower.dll", EntryPoint = "ResetModule", CharSet = CharSet.Ansi, SetLastError = true)]
        public static extern int ResetModule(int port);


        static void Main(string[] args)
        {
            CommandLine.Parser.Default.ParseArguments<Options>(args)
               .WithParsed(opts =>
               {
                   if (opts.PowerStatus == null && !opts.ModuleReset)
                   {
                       GetStatus(opts);
                   }
                   else if (opts.PowerStatus != null)
                   {
                       SetPowerStatus(opts);
                   }
                   else if (opts.ModuleReset)
                   {

                       Reset5GModule(opts);
                   }

               });
        }

        private static void GetStatus(Options opts)
        {
            int port = opts.SocketIndex - 1;
            int status = GetPowerStatus(port);
            if (status < 0)
                Console.WriteLine("Failed to get 5G module status");
            else if (status == 1)
                Console.WriteLine("5G module status: ON");
            else if (status == 0)
                Console.WriteLine("5G module status: OFF");
        }


        private static void SetPowerStatus(Options opts)
        {
            int port = opts.SocketIndex - 1;
            int status = (int)opts.PowerStatus;
            if (SetPowerStatus(port, status) < 0)
            {
                Console.WriteLine("Failed to set 5G module status.");
            }
            else
            {
                if (status == 1)
                    Console.WriteLine("Set 5G module power on.");
                else
                    Console.WriteLine("Set 5G module power off.");
            }
        }

        private static void Reset5GModule(Options opts)
        {
            int port = opts.SocketIndex - 1;
            int status = ResetModule(port);
            if (status < 0)
                Console.WriteLine("Failed to reset 5G module.");
            else
                Console.WriteLine("5G module reset.");
        }


    }
}
