using CefSharp;
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Linq;

namespace CefSharpWrap.CustomResource
{
    internal class CustomResourceSchemeHandlerFactory : ISchemeHandlerFactory
    {
        internal static readonly ConcurrentDictionary<string, Tuple<string, IBytesProvider>> PathResources = new ConcurrentDictionary<string, Tuple<string, IBytesProvider>>();
        internal static readonly ConcurrentDictionary<string, ICustomResourceResolver> PathPrefixResolvers = new ConcurrentDictionary<string, ICustomResourceResolver>();

        public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request)
        {
            var path = new Uri(request.Url).LocalPath;
            if (PathResources.TryGetValue(path, out var tuple)) return new ResourceHandler(tuple.Item1, new MemoryStream(tuple.Item2.GetBytes()), true);

            var pathPrefix = PathPrefixResolvers.Keys.FirstOrDefault(p => path.StartsWith(p));
            if (null == pathPrefix) return null;

            var keys = PathPrefixResolvers.Keys.Where(p => path.StartsWith(p)).OrderByDescending(p => p.Length);
            return keys
                .Select(key => PathPrefixResolvers[key].Resolve(path.Substring(pathPrefix.Length)))
                .Where(result => null != result)
                .Select(result => new ResourceHandler(result.Mime, result.Stream, false == result.Reuseable))
                .FirstOrDefault();
        }
    }
}