using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;

namespace Jovian.ProjectSettings {
    /// <summary>
    /// Reads and writes settings to ProjectSettings/CustomLoggerSettings.json.
    /// Flat key-value store. Use prefixed keys by convention (e.g. "logger.myKey").
    /// </summary>
    internal static class JovianProjectSettings {
        private const string FileName = "CustomLoggerSettings.json";

        private static string FilePath {
            get {
                var fullName = Directory.GetParent(Application.dataPath)?.FullName;
                return Path.Combine(fullName ?? Application.dataPath, "ProjectSettings", FileName);
            }
        }

        internal static T Get<T>(string packagePrefix, string setting, T defaultValue) {
            var root = LoadRoot();
            var key = $"{packagePrefix}.{setting}";
            if (root.TryGetValue(key, out var token)) {
                try {
                    return token.ToObject<T>();
                } catch {
                    return defaultValue;
                }
            }

            return defaultValue;
        }

        internal static void Set<T>(string packagePrefix, string setting, T value) {
            var root = LoadRoot();
            var key = $"{packagePrefix}.{setting}";
            root[key] = value != null ? JToken.FromObject(value) : JValue.CreateNull();
            SaveRoot(root);
        }

        private static JObject LoadRoot() {
            string path = FilePath;
            if (!File.Exists(path)) {
                return new JObject();
            }

            try {
                string json = File.ReadAllText(path);
                return JObject.Parse(json);
            } catch {
                return new JObject();
            }
        }

        private static void SaveRoot(JObject root) {
            string path = FilePath;
            string dir = Path.GetDirectoryName(path);
            if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) {
                Directory.CreateDirectory(dir);
            }

            string json = root.ToString(Formatting.Indented);
            File.WriteAllText(path, json);
        }
    }
}
