using System;
using System.Collections.Generic;

namespace Example
{
	public static class Procedures
	{
		public static IEnumerator<(int?, int?)> IncrementInteger(int? i)
		{
			yield return (i, i + 1);
		}

		public static IEnumerator<(long?, long?)> IncrementBigint(long? i)
		{
			yield return (i, i + 1);
		}

		public static IEnumerator<(short?, short?)> IncrementSmallint(short? i)
		{
			yield return (i, (short?)(i + 1));
		}

		public static IEnumerator<(float?, float?)> IncrementFloat(float? i)
		{
			yield return (i, i + 1);
		}

		public static IEnumerator<(double?, double?)> IncrementDouble(double? i)
		{
			yield return (i, i + 1);
		}

		public static IEnumerator<(decimal?, decimal?)> IncrementDecimal(decimal? i)
		{
			yield return (i, i + 1);
		}

		public static IEnumerator<(decimal?, decimal?)> IncrementNumeric(decimal? i)
		{
			yield return (i, i + 1);
		}

		public static IEnumerator<(string, string)> ReverseVarchar(string s)
		{
			yield return (s, s?.Reverse());
		}

		public static IEnumerator<(string, string)> ReverseChar(string s)
		{
			yield return (s, s?.Reverse());
		}

		public static IEnumerator<(DateTime?, DateTime?)> AddDayTimestamp(DateTime? timestamp)
		{
			yield return (timestamp, timestamp?.AddDays(1));
		}

		public static IEnumerator<(DateTime?, DateTime?)> AddDayDate(DateTime? date)
		{
			yield return (date, date?.AddDays(1));
		}

		public static IEnumerator<(TimeSpan?, TimeSpan?)> AddHourTime(TimeSpan? time)
		{
			yield return (time, time?.Add(TimeSpan.FromHours(1)));
		}

		public static IEnumerator<(bool?, bool?)> NegateBoolean(bool? b)
		{
			yield return (b, !b);
		}

		public static IEnumerator<ValueTuple<DateTime?>> CurrentUtcTimestamp()
		{
			var value = DateTime.UtcNow;
			yield return new ValueTuple<DateTime?>(value);
		}
	}

	public static class Ext
	{
		public static string Reverse(this string s)
		{
			var chars = s.ToCharArray();
			Array.Reverse(chars);
			return new string(chars);
		}
	}
}
