// produces outputs for all defined configs using the given metadata info
 static void Execute(WinampMetadata metadata, OutputConfigs outputs)
 {
     foreach (var cfg in outputs.Configs)
     {
         string result = cfg.Formatting;
         foreach (var replacement in metadataReplacements)
         {
             result = result.Replace(replacement.Key, replacement.Value.GetValue(metadata) as string);
         }
         System.IO.File.WriteAllText(cfg.FileTarget, result);
     }
 }
        static void Main(string[] args)
        {
            if (!File.Exists(configFileName))
            {
                Console.WriteLine($"Cannot find configuration file [{configFileName}]");
                return;
            }

            string configData = File.ReadAllText("config.json");

            if (string.IsNullOrEmpty(configData))
            {
                Console.WriteLine($"Config file [{configFileName}] empty");
                return;
            }

            OutputConfigs cfg;

            try
            {
                cfg = JsonConvert.DeserializeObject <OutputConfigs>(configData);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Config file deserialize failed, {ex.Message}");
                return;
            }

            PropertyInfo[] properties = typeof(WinampMetadata).GetProperties();
            foreach (PropertyInfo property in properties)
            {
                metadataReplacements.Add($"%{property.Name}%", property);
            }


            // plug into the matrix
            SetupMemoryMapFile();

            bool wasNew      = false;
            var  globalMutex = new Mutex(false, cGlobalMutexName, out wasNew);

            for ( ; ;)
            {
                if (globalMutex.WaitOne(500))
                {
                    try
                    {
                        Int32 readLen = mmStream.Read(transmissionBuffer, 0, cSharedBufferSize);
                        mmStream.Seek(0, SeekOrigin.Begin);

                        int transmissionID = BitConverter.ToInt32(transmissionBuffer, 0);
                        int stringLength   = BitConverter.ToInt32(transmissionBuffer, 4);

                        bool recvOK = (transmissionID & 0xFF000000) == 0x6A000000;
                        transmissionID &= 0x00FFFFFF;

                        Console.WriteLine($"------------ sync:{recvOK} @ {transmissionID} --");

                        if (recvOK && stringLength != 0)
                        {
                            string result = System.Text.Encoding.ASCII.GetString(transmissionBuffer, 8, stringLength);

                            WinampMetadata meta = JsonConvert.DeserializeObject <WinampMetadata>(result);

                            // uncomment to check/see the data in the console
                            // Console.WriteLine( JsonConvert.SerializeObject( meta, Formatting.Indented ) );

                            Execute(meta, cfg);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"ERROR: {ex.Message}");
                    }
                    finally
                    {
                        globalMutex.ReleaseMutex();
                    }
                }

                Thread.Sleep(5000);
                Console.WriteLine(".");
            }
        }