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

namespace mx_pciereset_ctl
{
    class Program
    {
        class Options
        {
            [Option('i', Required = true, HelpText = "-i <#PCIE Reset Slot index> (Start from 0)")]
            public uint RESETSlotIndex { get; set; }

            [Option('t', Required = false, HelpText = "-t <#PCIE Reset Delay time(ms)>")]
            public uint DelayTime { get; set; }

            [Usage(ApplicationAlias = "mx-pciereset-ctl")]
            public static IEnumerable<Example> Examples
            {
                get
                {
                    yield return new Example("Reset PCIE slot 1 ", new Options { RESETSlotIndex = 1 });
                    yield return new Example("Reset PCIE slot 1 DelayTime 200ms", new Options { RESETSlotIndex = 1, DelayTime = 200 });
                }
            }
        }

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

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

        public struct Action_Struct
        {
            public int index;
            public int time;
        };

        static void Main(string[] args)
        {
            CommandLine.Parser.Default.ParseArguments<Options>(args)
                .WithParsed(opts =>
                {
                    SetModeAction(opts);
                });
        }

        private static void SetModeAction(Options opts)
        {
            Action_Struct action;
            action.index = (int)opts.RESETSlotIndex;
            action.time = (int)opts.DelayTime;
            if (SetRESETSlotStatus(action.index, action.time) < 0)
            {
                Console.WriteLine("Failed to reset PCIE slot {0} power status.", action.index);
            }
            else
            {
                int status = GetRESETSlotStatus(action.index);
                if (status >= 0)
                {
                    Console.WriteLine(string.Format("PCIE slot {0} reset status: {1}", action.index, status));
                }
            }

        }

        private static void GetModeAction(Options opts)
        {
            Action_Struct action;
            action.index = (int)opts.RESETSlotIndex;
            int status = GetRESETSlotStatus(action.index);
            if (status >= 0)
            {
                Console.WriteLine(string.Format("PCIE slot {0} reset status: {1}", action.index, status));
            }
        }
    }
}
