using System.Diagnostics;


if (args.Length < 2)
{
    Console.WriteLine("Err: at least 2 args required, <inputDir> <outputDir> [-lossless]");
    return 1;
}

var inputDir = args[0];
var outputDir = args[1];

if (!Directory.Exists(inputDir))
{
    Console.WriteLine("Err: inputDir dose not exist");
    return 1;
}

if (!Directory.Exists(outputDir))
{
    Console.WriteLine("Err: outputDir dose not exist");
    return 1;
}

var flagLossLess = false;

if (args.Length > 2)
{
    if (args[2] == "-lossless")
    {
        flagLossLess = true;
    }
    else
    {
        Console.WriteLine("Warn: invalid arg#3, should be [-lossless], set lossless flag to false");
    }
}

Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.Idle;

var fullInputDir = Path.GetFullPath(inputDir);
var fullOutputDir = Path.GetFullPath(outputDir);

var filePathsToProcess = Directory.GetFiles(fullInputDir, "*", SearchOption.AllDirectories);

void ProcessFunc(string inputFilePath)
{
    var outputFilePath = Path.ChangeExtension(Path.Combine(fullOutputDir, inputFilePath[(fullInputDir.Length + 1)..]), ".webp");
    if (File.Exists(outputFilePath))
    {
        lock (Console.Out) Console.WriteLine("SKIP EXIST: " + outputFilePath);
        return;
    }

    var outputFileDir = Path.GetDirectoryName(outputFilePath);
    if (Directory.Exists(outputFileDir) == false)
    {
        lock (Console.Out) Console.WriteLine("Create dir: " + outputFileDir);
        Directory.CreateDirectory(outputFileDir);
    }

    var pWebp = new Process
    {
        StartInfo =
        {
            FileName = "cwebp",
            ArgumentList =
            {
                inputFilePath, "-o", outputFilePath , "-quiet"
            },
            UseShellExecute = false,
            CreateNoWindow = false,

        }
    };

    if (flagLossLess) pWebp.StartInfo.ArgumentList.Add("-lossless");

    pWebp.Start();
    pWebp.WaitForExit();

    lock (Console.Out) Console.WriteLine($"PROCESS {pWebp.ExitCode} {outputFilePath}");

    if (pWebp.ExitCode != 0)
    {
        int bp = 0;
    }
}

Parallel.ForEach(filePathsToProcess, ProcessFunc);

// for debug
//foreach (var s in filePathsToProcess)
//{
//    ProcessFunc(s);
//}

return 0;