using System;
using System.IO;
using System.Text.RegularExpressions;
using Microsoft.Data.SqlClient;

var connectionString = "Server=localhost;Database=PlotLine;User Id=PlotLineApp;Password=t6eb1cvd9bNB27czde#h9r;MultipleActiveResultSets=true;Encrypt=false;";
var scriptPath = args.Length > 0
    ? Path.GetFullPath(args[0])
    : throw new ArgumentException("Pass the SQL script path as the first argument.");

if (args.Length > 1 && !string.IsNullOrWhiteSpace(args[1]))
{
    connectionString = args[1];
}

var script = await File.ReadAllTextAsync(scriptPath);
var batches = Regex.Split(script, @"^\s*GO\s*$", RegexOptions.Multiline | RegexOptions.IgnoreCase);

await using var connection = new SqlConnection(connectionString);
await connection.OpenAsync();

var count = 0;
foreach (var batch in batches)
{
    if (string.IsNullOrWhiteSpace(batch))
    {
        continue;
    }

    await using var command = new SqlCommand(batch, connection);
    command.CommandTimeout = 120;
    await using var reader = await command.ExecuteReaderAsync();
    var resultSet = 0;
    do
    {
        if (reader.FieldCount > 0)
        {
            resultSet++;
            Console.WriteLine($"-- Result set {count + 1}.{resultSet}");
            var headers = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName);
            Console.WriteLine(string.Join("\t", headers));
            while (await reader.ReadAsync())
            {
                var values = Enumerable.Range(0, reader.FieldCount)
                    .Select(i => reader.IsDBNull(i) ? "NULL" : Convert.ToString(reader.GetValue(i))?.Replace("\r", "\\r").Replace("\n", "\\n"));
                Console.WriteLine(string.Join("\t", values));
            }
        }
    }
    while (await reader.NextResultAsync());

    count++;
}

Console.WriteLine($"Applied {count} SQL batches.");
