using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Http.Core
{
    public class PathBuilder
    {
        private readonly string _uriTemplate;
        private readonly List<string> _routeParams;

        private PathBuilder(string uriTemplate)
        {
            _uriTemplate = uriTemplate;
            _routeParams = new List<string>();
        }

        public static PathBuilder FromRouteTemplate(string urlTemplate)
        {
            return new PathBuilder(urlTemplate);
        }

        public PathBuilder AddRouteParams(params string[] routeParams)
        {
            _routeParams.AddRange(routeParams);
            return this;
        }

        public QueryBuilder ToQuery()
        {
            return new QueryBuilder(_uriTemplate, _routeParams);
        }

        public QueryBuilder AddQuery(string key, string value)
        {
            return ToQuery().AddQuery(key, value);
        }

        public string Build()
        {
            if (!_routeParams.Any())
                return _uriTemplate;

            return new StringBuilder()
                .AppendFormat(_uriTemplate, _routeParams.ToArray())
                .ToString();
        }

        public class QueryBuilder
        {
            private readonly string _uriTemplate;
            private readonly List<string> _routeParams;
            private readonly IDictionary<string, string> _queryParams;

            internal QueryBuilder(string uriTemplate, List<string> routeParams)
            {
                _uriTemplate = uriTemplate;
                _routeParams = routeParams;
                _queryParams = new Dictionary<string, string>();
            }

            public QueryBuilder AddQuery(string key, string value)
            {
                _queryParams[key] = Uri.EscapeDataString(value);
                return this;
            }

            public string Build()
            {
                var builder = new StringBuilder();

                if (_routeParams.Any())
                    builder.AppendFormat(_uriTemplate, _routeParams.ToArray());
                else
                    builder.Append(_uriTemplate);

                if (_queryParams.Any())
                {
                    builder.Append("?");
                    foreach (var keyValuePair in _queryParams)
                    {
                        builder.Append(keyValuePair.Key)
                               .Append('=')
                               .Append(keyValuePair.Value)
                               .Append('&');
                    }
                    builder.Remove(builder.Length - 1, 1); // remove last & character
                }
                return builder.ToString();
            }
        }
    }
}