using NetworkResurrector.Agent.Application.Services.Abstractions;
using System;
using System.Diagnostics;
using System.Text;

namespace NetworkResurrector.Agent.Application.Services.Windows
{
    internal class CmdService : ICliService
    {
        public (bool success, string message) Execute(string command) => Run("cmd.exe", command, null);
        public (bool success, string message) Shutdown(string arguments) => Run("shutdown.exe", null, arguments);

        private (bool success, string message) Run(string fileName, string command, string arguments)
        {
            var commandOutput = new StringBuilder();
            var commandErrors = new StringBuilder();

            var process = new Process();
            process.StartInfo.RedirectStandardError = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardInput = true;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.FileName = fileName;

            if (arguments != null)
                process.StartInfo.Arguments = arguments;

            commandOutput.Clear();
            commandErrors.Clear();

            process.OutputDataReceived += new DataReceivedEventHandler((s, e) =>
            {
                if (!string.IsNullOrEmpty(e.Data))
                    commandOutput.Append($"{e.Data}{Environment.NewLine}");
            });

            process.ErrorDataReceived += new DataReceivedEventHandler((s, e) =>
            {
                if (!string.IsNullOrEmpty(e.Data))
                    commandErrors.Append($"{e.Data}{Environment.NewLine}");
            });

            process.Start();

            if (command != null)
            {
                process.StandardInput.WriteLine(command);
                process.StandardInput.Flush();
                process.StandardInput.Close();
            }

            process.BeginOutputReadLine();
            process.BeginErrorReadLine();

            process.WaitForExit();

            var msg = new StringBuilder();

            if (commandOutput.Length > 0)
                msg.Append($"Output:{Environment.NewLine}{commandOutput}{Environment.NewLine}");

            if (commandErrors.Length > 0)
                msg.Append($"Errors:{Environment.NewLine}{commandErrors}{Environment.NewLine}");

            return (commandErrors.Length == 0, msg.ToString());
        }
    }
}
