using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;

namespace Evos.Api.Samples.Infrastructure
{
    /// Откуда CollaborationSample берёт адрес Collaboration-сервера. Сам сервер сэмплы не поднимают и не гасят:
    /// у пользователя он развёрнут, разработчик поднимает его локально, на TeamCity — шаг сборки.
    /// Переменные окружения важнее файла: так TeamCity задаёт адрес, ничего не коммитя в репозиторий.
    [Localizable(false)]
    internal sealed class CollaborationSettings
    {
        public const string UrlVariable = "EVOS_COLLABORATION_URL";

        /// Прогон, в котором пропуск CollaborationSample означает поломку, а не отсутствие сервера.
        public const string RequiredVariable = "EVOS_COLLABORATION_REQUIRED";

        private const string FileName = "collaboration.settings.json";
        private const string DefaultBranchName = "main";

        private static readonly JsonSerializerOptions FileOptions = new()
        {
            PropertyNameCaseInsensitive = true,
            ReadCommentHandling = JsonCommentHandling.Skip,
            AllowTrailingCommas = true
        };

        private CollaborationSettings(string serverUrl, string branchName)
        {
            ServerUrl = serverUrl;
            BranchName = branchName;
        }

        public string ServerUrl { get; }

        public string BranchName { get; }

        /// <c>false</c> — сервер не настроен: CollaborationSample нечего запускать.
        public static bool TryLoad([NotNullWhen(true)] out CollaborationSettings? settings)
        {
            var file = ReadFile();

            var serverUrl = FirstNotEmpty(Environment.GetEnvironmentVariable(UrlVariable), file?.ServerUrl);
            if (serverUrl is null)
            {
                settings = null;
                return false;
            }

            settings = new CollaborationSettings(
                serverUrl.TrimEnd('/'),
                FirstNotEmpty(file?.BranchName) ?? DefaultBranchName);

            return true;
        }

        public static bool IsServerRequired()
        {
            return !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(RequiredVariable));
        }

        private static SettingsFile? ReadFile()
        {
            var filePath = Path.Combine(AppContext.BaseDirectory, FileName);

            return File.Exists(filePath)
                ? JsonSerializer.Deserialize<SettingsFile>(File.ReadAllText(filePath), FileOptions)
                : null;
        }

        private static string? FirstNotEmpty(params string?[] values)
        {
            return values.FirstOrDefault(value => !string.IsNullOrWhiteSpace(value));
        }

        private sealed class SettingsFile
        {
            public string? ServerUrl { get; init; }

            public string? BranchName { get; init; }
        }
    }
}
