<commit_before>﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Json;
using Newtonsoft.Json;

namespace WOptiPNG
{
    public class WatchedDirectory
    {
        public string Path { get; set; }
        public bool WatchSubfolders { get; set; }
    }

    public class Settings
    {
        private Settings()
        {
            OverwriteSource = true;
            Threads = DefaultThreads;
            OptLevel = DefaultOptLevel;
            ProcessPriority = ProcessPriorityClass.Normal;
        }

        public bool OverwriteSource { get; set; }
        public string OutputDirectory { get; set; }
        public int Threads { get; set; }
        public int OptLevel { get; set; }
        public bool IncludeSubfolders { get; set; }
        public ProcessPriorityClass ProcessPriority { get; set; }

        private static int DefaultThreads { get { return Environment.ProcessorCount; } }
        private static int DefaultOptLevel { get { return 2; } }

        //windows service settings
        public ObservableCollection<WatchedDirectory> WatchedFolders { get; set; }
        public int ServiceThreads { get; set; }
        public ProcessPriorityClass ServiceProcessPriority { get; set; }
        public int ServiceOptLevel { get; set; }

        public bool SettingsValid()
        {
            return Threads > 0 && ServiceThreads > 0 && 
                OptLevel > 0 && OptLevel <= 8 &&
                ServiceOptLevel > 0 && ServiceOptLevel <= 8;
        }

        public void ResetBrokenSettings()
        {
            if (Threads <= 0)
            {
                Threads = DefaultThreads;
            }
            if (OptLevel <= 0 || OptLevel > 8)
            {
                OptLevel = DefaultOptLevel;
            }
            if (ServiceThreads <= 0)
            {
                ServiceThreads = Math.Max(1, DefaultThreads/4);
            }
            if (ServiceOptLevel <= 0 || ServiceOptLevel > 8)
            {
                ServiceOptLevel = DefaultOptLevel;
            }
        }

        public IEnumerable<string> GetBrokenSettingsNames()
        {
            if (SettingsValid())
            {
                return new string[0];
            }
            var names = new List<string>();
            if (Threads <= 0)
            {
                names.Add("threads");
            }
            if (OptLevel <= 0 || OptLevel > 8)
            {
                names.Add("optimization level");
            }
            if (ServiceThreads <= 0)
            {
                names.Add("service threads");
            }
            if (ServiceOptLevel <= 0 || ServiceOptLevel > 8)
            {
                names.Add("service optimization level");
            }
            return names;
        }

        public void WriteToFile()
        {
            var folder = Path.GetDirectoryName(SettingsPath);
            if (folder == null)
            {
                throw new IOException("Incorrect folder name");
            }
            if (!Directory.Exists(folder))
            {
                Directory.CreateDirectory(folder);
            }
            FilterOutNonexistentFolders();
            var str = JsonConvert.SerializeObject(this, Formatting.Indented);
            File.WriteAllText(SettingsPath, str);
        }

        private static string _settingsPath;
        public static string SettingsPath
        {
            get { return _settingsPath ?? (_settingsPath = Path.Combine(ApplicationDataPath, "settings.json")); }
        }

        public static string ApplicationDataPath
        {
            get
            {
                var appdata = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
                return Path.Combine(appdata, "WOptiPng");
            }
        }

        public static Settings ReadFromFile()
        {
            if (File.Exists(SettingsPath))
            {
                var text = File.ReadAllText(SettingsPath);
                var deserialised = JsonConvert.DeserializeObject<Settings>(text);
                deserialised.FilterOutNonexistentFolders();
                return deserialised;
            }
            var settings = new Settings();
            settings.WriteToFile();
            return settings;
        }

        private void FilterOutNonexistentFolders()
        {
            foreach (var wf in WatchedFolders.ToList())
            {
                if (!Directory.Exists(wf.Path))
                {
                    WatchedFolders.Remove(wf);
                }
            }
        }
    }
}<commit_msg>Add missing null check to settings reader/writer<commit_after>﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Json;
using Newtonsoft.Json;

namespace WOptiPNG
{
    public class WatchedDirectory
    {
        public string Path { get; set; }
        public bool WatchSubfolders { get; set; }
    }

    public class Settings
    {
        private Settings()
        {
            OverwriteSource = true;
            Threads = DefaultThreads;
            OptLevel = DefaultOptLevel;
            ProcessPriority = ProcessPriorityClass.Normal;
        }

        public bool OverwriteSource { get; set; }
        public string OutputDirectory { get; set; }
        public int Threads { get; set; }
        public int OptLevel { get; set; }
        public bool IncludeSubfolders { get; set; }
        public ProcessPriorityClass ProcessPriority { get; set; }

        private static int DefaultThreads { get { return Environment.ProcessorCount; } }
        private static int DefaultOptLevel { get { return 2; } }

        //windows service settings
        public ObservableCollection<WatchedDirectory> WatchedFolders { get; set; }
        public int ServiceThreads { get; set; }
        public ProcessPriorityClass ServiceProcessPriority { get; set; }
        public int ServiceOptLevel { get; set; }

        public bool SettingsValid()
        {
            return Threads > 0 && ServiceThreads > 0 && 
                OptLevel > 0 && OptLevel <= 8 &&
                ServiceOptLevel > 0 && ServiceOptLevel <= 8;
        }

        public void ResetBrokenSettings()
        {
            if (Threads <= 0)
            {
                Threads = DefaultThreads;
            }
            if (OptLevel <= 0 || OptLevel > 8)
            {
                OptLevel = DefaultOptLevel;
            }
            if (ServiceThreads <= 0)
            {
                ServiceThreads = Math.Max(1, DefaultThreads/4);
            }
            if (ServiceOptLevel <= 0 || ServiceOptLevel > 8)
            {
                ServiceOptLevel = DefaultOptLevel;
            }
        }

        public IEnumerable<string> GetBrokenSettingsNames()
        {
            if (SettingsValid())
            {
                return new string[0];
            }
            var names = new List<string>();
            if (Threads <= 0)
            {
                names.Add("threads");
            }
            if (OptLevel <= 0 || OptLevel > 8)
            {
                names.Add("optimization level");
            }
            if (ServiceThreads <= 0)
            {
                names.Add("service threads");
            }
            if (ServiceOptLevel <= 0 || ServiceOptLevel > 8)
            {
                names.Add("service optimization level");
            }
            return names;
        }

        public void WriteToFile()
        {
            var folder = Path.GetDirectoryName(SettingsPath);
            if (folder == null)
            {
                throw new IOException("Incorrect folder name");
            }
            if (!Directory.Exists(folder))
            {
                Directory.CreateDirectory(folder);
            }
            FilterOutNonexistentFolders();
            var str = JsonConvert.SerializeObject(this, Formatting.Indented);
            File.WriteAllText(SettingsPath, str);
        }

        private static string _settingsPath;
        public static string SettingsPath
        {
            get { return _settingsPath ?? (_settingsPath = Path.Combine(ApplicationDataPath, "settings.json")); }
        }

        public static string ApplicationDataPath
        {
            get
            {
                var appdata = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
                return Path.Combine(appdata, "WOptiPng");
            }
        }

        public static Settings ReadFromFile()
        {
            if (File.Exists(SettingsPath))
            {
                var text = File.ReadAllText(SettingsPath);
                var deserialised = JsonConvert.DeserializeObject<Settings>(text);
                deserialised.FilterOutNonexistentFolders();
                return deserialised;
            }
            var settings = new Settings();
            settings.WriteToFile();
            return settings;
        }

        private void FilterOutNonexistentFolders()
        {
            if (WatchedFolders == null)
            {
                return;
            }
            foreach (var wf in WatchedFolders.ToList())
            {
                if (!Directory.Exists(wf.Path))
                {
                    WatchedFolders.Remove(wf);
                }
            }
        }
    }
}
{'fraction_non_alphanumeric': 0.08351648351648351, 'fraction_numerical': 0.004604918890633176, 'mean_word_length': 1.487893777662067, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3472150', 'n_tokens_mistral': 2386, 'n_tokens_neox': 2273, 'n_words': 560}