using System;
using System.Diagnostics;
using System.Net.Sockets;

namespace TimedShutdown
{
    public class ShutdownManager
    {
        private readonly Func<bool, string> _funcForceShutdown = ForceShutdown;
        private readonly Func<Operation, string> _funcShutdownOperation = ShutdownOperation;
        private readonly Func<string, string> _funcRemoteShutdown = RemoteShutdown;

        public enum Operation
        {
            Shutdown,
            Reboot
        }

        /// <summary>
        /// Shuts down or reboots machine based on parameters.
        /// </summary>
        /// <param name="shutdownoperation"></param>
        /// <param name="shutdownSeconds"></param>
        /// <param name="forceShutdownState"></param>
        public void ExecuteOperation(Operation shutdownoperation, int shutdownSeconds, bool forceShutdownState, string remoteShutdown)
        {
            ProcessStartInfo info = new ProcessStartInfo();
            Process proc = new Process();

            info.FileName = "cmd.exe";
            info.Arguments = $"/c shutdown {_funcShutdownOperation(shutdownoperation)} -t" +
                                        $" {shutdownSeconds}" +
                                        $" {_funcForceShutdown(forceShutdownState)}" +
                                        $" {_funcRemoteShutdown(remoteShutdown)}";
            info.WindowStyle = ProcessWindowStyle.Hidden;
            info.CreateNoWindow = true;

            proc.StartInfo = info;
            proc.Start();
        }

        public void AbortOperation(string remoteShutdown)
        {
            ProcessStartInfo info = new ProcessStartInfo();
            Process proc = new Process();

            info.FileName = "cmd.exe";
            info.Arguments = $"/c shutdown -a {_funcRemoteShutdown(remoteShutdown)}";
            info.CreateNoWindow = true;
            info.WindowStyle = ProcessWindowStyle.Hidden;

            proc.StartInfo = info;
            proc.Start();
        }

        #region Functions

        private static string ShutdownOperation(Operation arg)
        {
            switch (arg)
            {
                case Operation.Shutdown:
                    return "-s";
                case Operation.Reboot:
                    return "-r";
                default:
                    return String.Empty;
            }
        }

        private static string ForceShutdown(bool arg)
        {
            return "-f";
        }

        private static string RemoteShutdown(string arg)
        {
            if (string.IsNullOrEmpty(arg)) return string.Empty;
            if (arg.StartsWith(@"\\"))
            {
                return $"-m {arg}";
            }
            return $@"-m \\{arg}";
        }

        #endregion

    }
}
