using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Tesses.Http
{
        /// <summary>
    /// mount multiple servers at different url paths
    /// </summary>
    public sealed class MountableServer : IRequestHandler
    {
        Dictionary<string, IRequestHandler> _servers = new Dictionary<string, IRequestHandler>();
        public MountableServer(IRequestHandler root)
        {
            _root = root;
        }
        IRequestHandler _root;
        private (string Key,IRequestHandler Value) GetFromPath(ServerContext ctx)
        {
            string path = ctx.Request.GetQueryParameters(ctx.Request.CurrentUrl,new Dictionary<string, List<string>>());
            //bool j = false;
           foreach(var item in _servers.Reverse())
            {
                if(path.StartsWith(item.Key,StringComparison.Ordinal))
                {
                    return (item.Key,RequestHandler.Guaranteed(ctx,item.Value));
                }
                if (path == item.Key.TrimEnd('/'))
                {
                    path += "/";
                    return (item.Key,RequestHandler.Guaranteed(ctx,item.Value));
                }
            }
            //Console.WriteLine("HERE WE ARE");
            return ("/",RequestHandler.Guaranteed(ctx,_root));
        }
        /// <summary>
        /// Mount the specified url and server.
        /// Must mount like this
        /// /somePath0
        /// /somePath0/someSubPath0
        /// /somePath0/someSubPath0/someSubSubPath0
        /// /somePath0/someSubPath0/someSubSubPath1
        /// /somePath0/someSubPath1
        /// /somePath0/someSubPath1/someSubSubPath0
        /// /somePath0/someSubPath1/someSubSubPath1
        /// </summary>
        /// <param name="url">URL.</param>
        /// <param name="server">Server.</param>
        public void Mount(string url,IRequestHandler server)
        {
            _servers.Add(url, server);
        }
        /// <summary>
        /// Unmount a server
        /// </summary>
        /// <param name="url">Url</param>
        public void Unmount(string url)
        {
            _servers.Remove(url);
        }
        /// <summary>
        /// Unmount all servers
        /// </summary>
        public void UnmountAll()
        {
            _servers.Clear();
            
        }
        
        public async Task Handle(ServerContext ctx)
        {
            var v = GetFromPath(ctx);
            string[] curUrl =ctx.Request.CurrentUrl.Split(new char[]{'?'},2,StringSplitOptions.RemoveEmptyEntries);
            string url = '/' + curUrl[0].Substring(v.Key.Length).TrimStart('/');

            if(curUrl.Length > 1)
            {
                url += $"?{curUrl[1]}";
            }
            ctx.Request.CurrentUrl = url;

            await v.Value.Handle(ctx);
        }
       
       
    }
 
}