using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using VCommon.IO;

namespace VCommon.VSwaggerUI
{
    public class SwaggerUiResourceProvider : ISwaggerUiResourceProvider
    {
        public static ISwaggerUiResourceProvider Version1 => Version1LazyHolder.Instance;
        public static ISwaggerUiResourceProvider Version2 => Version2LazyHolder.Instance;

        //------------------------------------------------

        private static readonly LazyHolder<SwaggerUiResourceProvider> Version1LazyHolder = new LazyHolder<SwaggerUiResourceProvider>(() => new SwaggerUiResourceProvider(typeof(Version1._NamespaceHolder).Namespace));

        private static readonly LazyHolder<SwaggerUiResourceProvider> Version2LazyHolder = new LazyHolder<SwaggerUiResourceProvider>(() => new SwaggerUiResourceProvider(typeof(Version2._NamespaceHolder).Namespace));

        //------------------------------------------------

        private readonly string _resourceNamespace;
        private readonly IReadOnlyDictionary<string, byte[]> _cachedBinResource;

        internal SwaggerUiResourceProvider(string embeddedResourceNamespace)
        {
            _resourceNamespace = embeddedResourceNamespace;
            var assembly = Assembly.GetExecutingAssembly();
            _cachedBinResource = assembly.GetManifestResourceNames()
                .Where(p => p.StartsWith(_resourceNamespace))
                .ToDictionary(p => p, p => assembly.GetManifestResourceStream(p).ReadFully());
        }

        public byte[] GetBinResource(string name)
        {
            return _cachedBinResource.TryGetValue(_resourceNamespace + "." + name, out var data)
                ? data
                : null;
        }

        public string GetIndex(string api)
        {
            var html = System.Text.Encoding.UTF8.GetString(GetBinResource("index.html"));
            html = html.Replace("$(API_PATH_WITHOUT_ROOT)", api);
            return html;
        }
    }
}