// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT License.
// See the LICENSE file in the project root for more information. 
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace System.Linq
{
    public static partial class AsyncEnumerable
    {
        /// 
        /// Returns an empty async-enumerable sequence.
        /// 
        /// The type used for the  type parameter of the resulting sequence.
        /// An async-enumerable sequence with no elements.
        public static IAsyncEnumerable Empty() => EmptyAsyncIterator.Instance;
        internal sealed class EmptyAsyncIterator : IAsyncPartition, IAsyncEnumerator
        {
            public static readonly EmptyAsyncIterator Instance = new EmptyAsyncIterator();
            public TValue Current => default!;
            public ValueTask GetCountAsync(bool onlyIfCheap, CancellationToken cancellationToken) => new ValueTask(0);
            public IAsyncPartition Skip(int count) => this;
            public IAsyncPartition Take(int count) => this;
            public ValueTask ToArrayAsync(CancellationToken cancellationToken) => new ValueTask(
#if NO_ARRAY_EMPTY
                EmptyArray.Value
#else
                Array.Empty()
#endif
                );
            public ValueTask> ToListAsync(CancellationToken cancellationToken) => new ValueTask>(new List());
            public ValueTask> TryGetElementAtAsync(int index, CancellationToken cancellationToken) => new ValueTask>(new Maybe());
            public ValueTask> TryGetFirstAsync(CancellationToken cancellationToken) => new ValueTask>(new Maybe());
            public ValueTask> TryGetLastAsync(CancellationToken cancellationToken) => new ValueTask>(new Maybe());
            public ValueTask MoveNextAsync() => new ValueTask(false);
            public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken)
            {
                cancellationToken.ThrowIfCancellationRequested(); // NB: [LDM-2018-11-28] Equivalent to async iterator behavior.
                return this;
            }
            public ValueTask DisposeAsync() => default;
        }
    }
}