using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text;

namespace Microsoft.AspNetCore.SpaServices.Prerendering
{
    /// <summary>
    /// Describes the prerendering result returned by JavaScript code.
    /// </summary>
    public class RenderToStringResult
    {
        /// <summary>
        /// If set, specifies JSON-serializable data that should be added as a set of global JavaScript variables in the document.
        /// This can be used to transfer arbitrary data from server-side prerendering code to client-side code (for example, to
        /// transfer the state of a Redux store).
        /// </summary>
        public JObject Globals { get; set; }

        /// <summary>
        /// The HTML generated by the prerendering logic.
        /// </summary>
        public string Html { get; set; }

        /// <summary>
        /// If set, specifies that instead of rendering HTML, the response should be an HTTP redirection to this URL.
        /// This can be used if the prerendering code determines that the requested URL would lead to a redirection according
        /// to the SPA's routing configuration.
        /// </summary>
        public string RedirectUrl { get; set; }

        /// <summary>
        /// If set, specifies the HTTP status code that should be sent back with the server response.
        /// </summary>
        public int? StatusCode { get; set; }

        /// <summary>
        /// Constructs a block of JavaScript code that assigns data from the
        /// <see cref="Globals"/> property to the global namespace.
        /// </summary>
        /// <returns>A block of JavaScript code.</returns>
        public string CreateGlobalsAssignmentScript()
        {
            if (Globals == null)
            {
                return string.Empty;
            }

            var stringBuilder = new StringBuilder();

            foreach (var property in Globals.Properties())
            {
                stringBuilder.AppendFormat("window.{0} = {1};",
                    property.Name,
                    property.Value.ToString(Formatting.None));
            }

            return stringBuilder.ToString();
        }
    }
}