#!/usr/bin/env dotnet-script

{
    const string header =
@"// Autogenerated
namespace InitableService;
";

    const string footer = "";
    using var initableWriter = File.CreateText("Initable.cs");
    initableWriter.WriteLine(header);
    const int generateForParams = 15;

    for (var i = 0; i <= generateForParams; i++)
    {
        WriteInitable(initableWriter, false, i);
    }

    for (var i = 0; i <= generateForParams; i++)
    {
        WriteInitable(initableWriter, true, i);
        initableWriter.WriteLine();
    }

    initableWriter.WriteLine(footer);
    initableWriter.Flush();
}

void WriteInitable(StreamWriter initableWriter, bool isAsync, int i)
{
    initableWriter.Write($"public interface I{(isAsync ? "Async" : "")}Initable");
    if (i > 0)
    {
        initableWriter.Write("<");
        initableWriter.Write(string.Join(", ", Enumerable.Range(1, i).Select(c => "T" + c)));
        initableWriter.Write(">");
    }

    initableWriter.WriteLine();
    initableWriter.WriteLine("{");

    if (isAsync)
    {
        initableWriter.Write("\tTask InitAsync");
    }
    else
    {
        initableWriter.Write("\tvoid Init");
    }

    if (i > 0)
    {
        /*initableWriter.Write("<");
        initableWriter.Write(string.Join(", ", Enumerable.Range(1, i).Select(c => "T" + c)));
        initableWriter.Write(">");*/
        initableWriter.Write("(");
        initableWriter.Write(string.Join(", ", Enumerable.Range(1, i).Select(c => $"T{c} obj{c}")));
        initableWriter.Write(")");
    }
    else
    {
        initableWriter.Write("()");
    }
    initableWriter.WriteLine(";");
    initableWriter.WriteLine("}");
}