// <auto-generated />

#pragma warning disable

using System;
using System.Diagnostics;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.CodeAnalysis;

namespace Polyfills;

[Embedded]
internal static partial class Polyfill
{
#if !NET

    /// <summary>
    /// Instructs the Process component to wait for the associated process to exit, or
    /// for the <paramref name="cancellationToken"/> to be canceled.
    /// </summary>
    public static async Task WaitForExitAsync(this Process target, CancellationToken cancellationToken = default)
    {
        if (!target.HasExited)
        {
            cancellationToken.ThrowIfCancellationRequested();
        }

        try
        {
            target.EnableRaisingEvents = true;
        }
        catch (InvalidOperationException)
        {
            if (target.HasExited)
            {
                // await WaitUntilOutputEOF(cancellationToken).ConfigureAwait(false);
                return;
            }

            throw;
        }

        var tcs = new TaskCompletionSource<object?>(TaskCreationOptions.RunContinuationsAsynchronously);

        EventHandler handler = (_, _) => tcs.TrySetResult(null);
        target.Exited += handler;

        try
        {
            if (!target.HasExited)
            {
                // NOTE: BCL uses UnsafeRegister instead.
                using (cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken)))
                {
                    await tcs.Task.ConfigureAwait(false);
                }
            }

            // await WaitUntilOutputEOF(cancellationToken).ConfigureAwait(false);
        }
        finally
        {
            target.Exited -= handler;
        }
    }
#endif
}
