using System.IO; using System.IO.Compression; using System.Linq; using System.Text.Json; using ParadoxSaveParser.Lib; namespace ParadoxSaveParser.CLI; internal static partial class Modes { internal static void Search(string searchQuery, IOPath inputPath, IOPath? outputPath) { Stream inputStream = File.OpenRead(inputPath); try { byte[] head4 = new byte[4]; inputStream.ReadExactly(head4); inputStream.Seek(0, SeekOrigin.Begin); if (head4.SequenceEqual([(byte)'P', (byte)'K', 3, 4])) { var zipArchive = new ZipArchive(inputStream, ZipArchiveMode.Read); var zipEntry = zipArchive.Entries.FirstOrDefault(e => e.Name == "gamestate"); if (zipEntry is null) throw new Exception("'gamestate' file not found in zip archive"); var unzipped = new MemoryStream((int)zipEntry.Length); zipEntry.Open().CopyTo(unzipped); zipArchive.Dispose(); // closes inputStream unzipped.Seek(0, SeekOrigin.Begin); inputStream = unzipped; } using var outputStream = outputPath is null ? Console.OpenStandardOutput() : File.OpenWrite(outputPath.Value); var searchExpression = SearchExpressionCompiler.Compile(searchQuery); var parser = new SaveParserEU4(inputStream, searchExpression); var parsedValue = parser.Parse(); JsonSerializer.Serialize(outputStream, parsedValue, ParsedValueJsonContext.Default.DictionaryStringObject); outputStream.WriteByte((byte)'\n'); } finally { inputStream.Dispose(); } } }