namespace AnonymousFunctions;

public static class VariableFromContainingMethod
{
    public static Predicate<int> IsGreaterThan(int threshold)
    {
        return value => value > threshold;
    }

    // Ten przykład pokazuje co generuje kompilator, jednak ponieważ zawiera 
    // nieprawidłowy identyfikator, nie można go skompilować. Stąd został on 
    // umieszczony w bloku #if false
#if false
    [CompilerGenerated]
    private sealed class <>c__DisplayClass1_0
    {
        public int threshold;

        public bool <IsGreaterThan>b__0(int value)
        {
            return (value > this.threshold);
        }
    }
#endif
    static void Calculate(int[] nums)
    {
        int zeroCount = 0;
        int[] nonZeroNums = Array.FindAll(
            nums,
            v =>
            {
                if (v == 0)
                {
                    zeroCount += 1;
                    return false;
                }
                else
                {
                    return true;
                }
            });
        Console.WriteLine($"Liczba elementów o wartości {zeroEntryCount}");
        Console.WriteLine($"Pierwszy element różny od 0: {nonZeroNums[0]}");
    }

    public static void PrematureDisposal()
    {
        HttpClient http = GetHttpClient();
        using (FileStream file = File.OpenWrite(@"c:\temp\page.txt"))
        {
            http.GetStreamAsync("https://endjin.com/")
                .ContinueWith((Task<Stream> t) => t.Result.CopyToAsync(file));
        } // Obiekt StreamStrem zostanie najprawdopodobniej zwolniony, 
          // zanim zostanie wywołana metoda zwrotna.
    }

    private static HttpClient GetHttpClient() => new();

    public static void Caught()
    {
        var greaterThanN = new Predicate<int>[10];
        for (int i = 0; i < greaterThanN.Length; ++i)
        {
            greaterThanN[i] = value => value > i; // Nieprawidłowe użycie zmiennej i
        }

        Console.WriteLine(greaterThanN[5](20));
        Console.WriteLine(greaterThanN[5](6));
    }

    public static void FixedCaught()
    {
        var greaterThanN = new Predicate<int>[10];
        for (int i = 0; i < greaterThanN.Length; ++i)
        {
            int current = i;
            greaterThanN[i] = value => value > current;
        }

        Console.WriteLine(greaterThanN[5](20));
        Console.WriteLine(greaterThanN[5](6));
    }

    public static void CaptureAtMultipleScopes()
    {
        var greaterThanN = new Predicate<int>[10];

        int offset = 10;
        for (int i = 0; i < greaterThanN.Length; ++i)
        {
            int current = i;
                greaterThanN[i] = value => value > (current + offset);
        }
    }

    public static Predicate<int> IsGreaterThan10() => static value => value > 10;
}
