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

namespace Quadarax.Foundation.Core.Value
{
    /// <summary>
    /// Represents a string with parameters (bracked by defined tags) that can be replaced.
    /// Sample: Hello {name}, how are you?
    /// If name = John, the result will be: Hello John, how are you?
    /// </summary>
    public class ParameterizedString
    {
        private readonly string _parameterPrefix;
        private readonly string _parameterPostfix;
        private readonly string _initialString;
        private readonly IDictionary<string, string> _parameters;

        public string[] Parameters => _parameters.Keys.ToArray();

        /// <summary>
        /// Creates a new instance of the ParameterizedString class.
        /// </summary>
        /// <param name="initialString">Initial string with parameters thats bracked by <paramref name="parameterPrefix"/> and <paramref name="parameterPostfix"/> </param>
        /// <param name="parameterPrefix">Left parameter name bracket</param>
        /// <param name="parameterPostfix">Right parameter name bracket</param>
        public ParameterizedString(string initialString,string parameterPrefix = "", string parameterPostfix = "")
        {
            _parameterPostfix = parameterPostfix;
            _parameterPrefix = parameterPrefix;

            _initialString = initialString;
            _parameters = new Dictionary<string, string>();
        }

        /// <summary>
        /// Add new parameter with value.
        /// </summary>
        /// <param name="name">Parameter name.</param>
        /// <param name="value">Parameter value</param>
        /// <returns>If parameter already exists, returns false</returns>
        public bool AddParameter(string name, string value)
        {
            if(_parameters.ContainsKey(name))
            {
                return false;
            }
            _parameters.Add(name, value);
            return true;
        }

        /// <summary>
        /// Set existing parameter value.
        /// </summary>
        /// <param name="name">Parameter name.</param>
        /// <param name="value">Parameter value</param>
        /// <returns>If parameter not exists, returns false</returns>
        public bool SetParameter(string name, string value)
        {
            if(!_parameters.ContainsKey(name))
            {
                return false;
            }
            _parameters[name] = value;
            return true;
        }
		
		/// <summary>
        /// Add or Set existing parameter value.
        /// </summary>
        /// <param name="name">Parameter name.</param>
        /// <param name="value">Parameter value</param>
        public void AddOrSetParameter(string name, string value)
        {
            if(!SetParameter(name, value))
				AddParameter(name, value);
        }

        /// <summary>
        /// Renders the string with the parameters.
        /// </summary>
        /// <returns>Transalted string</returns>
        public override string ToString()
        {
            var sb = new StringBuilder(_initialString);
            foreach (var key in _parameters.Keys)
            {
                sb.Replace(_parameterPrefix + key + _parameterPostfix, _parameters[key]);
            }
            return sb.ToString();
        }
    }
}
