// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System;

internal static class ArgumentValidation
{
    internal static T OrThrowIfNull<T>([NotNull] this T? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null)
    {
        ArgumentNullException.ThrowIfNull(argument, paramName);
        return argument;
    }

    internal static T OrThrowIfNullWithMessage<T>(
        [NotNull] this T? argument,
        string message,
        [CallerArgumentExpression(nameof(argument))] string? paramName = null) =>
        argument is null ? throw new ArgumentNullException(paramName, message) : argument;

    internal static nint OrThrowIfZero(this nint argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null) =>
        argument == 0 ? throw new ArgumentNullException(paramName) : argument;

    internal static string OrThrowIfNullOrEmpty([NotNull] this string? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null)
    {
        ThrowIfNullOrEmpty(argument, paramName);
        return argument;
    }

    // .NET Framework analyzer is confused by the use of [NotNull] on the parameter of these methods, and thinks
    // that the parameter must be non-null when exiting the method, which is not the case as these methods throw
    // when the parameter is null. Suppress the warning for these methods.

#pragma warning disable CS8777 // Parameter must have a non-null value when exiting.

    internal static void ThrowIfNullOrEmpty([NotNull] this string? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null)
    {
        if (string.IsNullOrEmpty(argument))
        {
            throw new ArgumentNullException(paramName);
        }
    }

    internal static void ThrowIfNullOrEmptyWithMessage([NotNull] this string? argument, string message, [CallerArgumentExpression(nameof(argument))] string? paramName = null)
    {
        if (string.IsNullOrEmpty(argument))
        {
            throw new ArgumentNullException(paramName, message);
        }
    }

#pragma warning restore CS8777

    internal static void ThrowIfNull(HDC argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null)
    {
        if (argument.IsNull)
        {
            throw new ArgumentNullException(paramName);
        }
    }
}
