using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace r13.Helpers
{
    public static class CaptchaHelper
    {
        internal const string SessionKeyPrefix = "__Captcha";
        private const string ImgFormat = "<img src=\"{0}\" />"
                            + @"<input type=""hidden"" name=""{1}"" value=""{2}"" />";

        public static MvcHtmlString Captcha(this HtmlHelper html, string name)
        {
            // Pobranie GUID reprezentującego to wyzwanie
            string challengeGuid = Guid.NewGuid().ToString();
            // Generowanie i zapisywanie losowego tekstu odpowiedzi 
            var session = html.ViewContext.HttpContext.Session;
            session[SessionKeyPrefix + challengeGuid] = MakeRandomSolution();

            // Wygenerowanie znacznika <img> ze zniekształconym tekstem
            // oraz pola ukrytego z GUIDem wyzwania 
            var urlHelper = new UrlHelper(html.ViewContext.RequestContext);
            string url = urlHelper.Action("Render", "CaptchaImage", new { challengeGuid });
            string htmlToDisplay = string.Format(ImgFormat, url, name, challengeGuid);
            return MvcHtmlString.Create(htmlToDisplay);
        }

        private static string MakeRandomSolution()
        {
            Random rng = new Random();
            int length = rng.Next(5, 7);
            char[] buf = new char[length];
            for (int i = 0; i < length; i++)
                buf[i] = (char)('a' + rng.Next(26));
            return new string(buf);
        }

        public static bool VerifyAndExpireSolution(HttpContextBase context,
                                                   string challengeGuid,
                                                   string attemptedSolution)
        {
            // Od razu usuwamy rozwiązanie z sesji, aby zapobiec atakom powtarzania
            string solution = (string)context.Session[SessionKeyPrefix + challengeGuid];
            context.Session.Remove(SessionKeyPrefix + challengeGuid);

            return ((solution != null) && (attemptedSolution == solution));
        }

    }

}