using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace StandardScene.Signal
{
    /// <summary>信号插件 JSON 配置的路径解析、种子拷贝与读写。</summary>
    public static class SignalConfigStore
    {
        private static readonly object FileLock = new object();

        private static readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings
        {
            Formatting = Formatting.Indented,
            NullValueHandling = NullValueHandling.Ignore,
            Converters = { new StringEnumConverter() }
        };

        /// <summary>
        /// 相对路径依次尝试：工作目录、插件目录旁的 Config。
        /// 工作目录文件不存在时，若插件目录有样例则拷过去。
        /// </summary>
        public static string Resolve(string configuredPath)
        {
            if (string.IsNullOrWhiteSpace(configuredPath))
                configuredPath = Path.Combine("Config", "Signal", "stations.json");

            if (Path.IsPathRooted(configuredPath))
                return configuredPath;

            var working = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, configuredPath);
            if (File.Exists(working))
                return working;

            var sample = Path.Combine(
                Path.GetDirectoryName(typeof(SignalConfigStore).Assembly.Location) ?? "",
                configuredPath);
            if (File.Exists(sample))
            {
                try
                {
                    var dir = Path.GetDirectoryName(working);
                    if (!string.IsNullOrEmpty(dir))
                        Directory.CreateDirectory(dir);
                    File.Copy(sample, working, overwrite: false);
                }
                catch
                {
                    return File.Exists(working) ? working : sample;
                }
            }

            return working;
        }

        public static List<T> Load<T>(string path) where T : class
        {
            try
            {
                if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
                    return new List<T>();
                var json = File.ReadAllText(path);
                if (string.IsNullOrWhiteSpace(json))
                    return new List<T>();
                return JsonConvert.DeserializeObject<List<T>>(json, JsonSettings) ?? new List<T>();
            }
            catch
            {
                return new List<T>();
            }
        }

        public static void Save<T>(string path, IReadOnlyList<T> items)
        {
            var json = JsonConvert.SerializeObject(items ?? Array.Empty<T>(), JsonSettings);
            var dir = Path.GetDirectoryName(path);
            if (!string.IsNullOrEmpty(dir))
                Directory.CreateDirectory(dir);
            lock (FileLock)
                File.WriteAllText(path, json);
        }
    }
}
