/// <summary>
 /// Tries to create an Unused Short Code by creating a Random AlphaNumeric 
 /// sequence based on the ShortCodeLenth within X number of tries given 
 /// by the ShortCodeTriesBeforeFail variable
 /// </summary>
 /// <returns></returns>
 private static string CreateUnusedShortCode()
 {
     DbContext dbContext = new DbContext();
     for (int x = 0; x < ShortCodeTriesBeforeFail; x++)
     {
         string newKey = CreateRandomAlphaNumericSequence(ShortCodeLength);
         if (dbContext.Links.Where(i => i.ShortCode == newKey).Count() == 0)
             return newKey;
     }
     throw new Exception();
 }
 /// <summary>
 /// Gets the ShortCode and tries to find a RedirectUrl based on that code
 /// </summary>
 /// <param name="shortCode"></param>
 /// <returns></returns>
 public static string GetRedirectUrlFromShortCode(string shortCode)
 {
     DbContext dbContext = new DbContext();
     var link = dbContext.Links.Where(l => l.ShortCode == shortCode).First();
     link.DateOfLastVisit = DateTime.Now;
     link.VisitCount++;
     dbContext.SubmitChanges();
     return link.RedirectUrl;
 }
        /// <summary>
        /// Logs an authentication error to the database to prevent future requests until the wait time has lapsed
        /// </summary>
        /// <param name="ipAddress"></param>
        /// <param name="lastAttemptDate"></param>
        /// <param name="SecondsUntilNextAttempt"></param>
        public static void LogAuthorizationError(string ipAddress, out DateTime lastAttemptDate, out long SecondsUntilNextAttempt)
        {
            Attempt a = null;
            DbContext dbContext = new DbContext();
            lastAttemptDate = DateTime.Now;

            var allAttempts = dbContext.Attempts.Where(i => i.IPAddress == ipAddress);

            if (allAttempts.Count() == 0)
            {
                a = new Attempt();
                a.DateOfLastAttempt = lastAttemptDate;
                a.IPAddress = ipAddress;
                a.NumberOfAttemptsSinceLastSuccess = 1;
                a.SecondsUntilNextAttempt = Convert.ToInt64(FailWaitExtenderLength);
                dbContext.Attempts.InsertOnSubmit(a);
            }
            else
            {
                a = allAttempts.First();
                a.DateOfLastAttempt = lastAttemptDate;
                a.NumberOfAttemptsSinceLastSuccess++;
                var power = Math.Pow(FailWaitExtenderLength, a.NumberOfAttemptsSinceLastSuccess);

                a.SecondsUntilNextAttempt = Convert.ToInt64(power);
            }
            dbContext.SubmitChanges();

            //return seconds until when they can try again
            SecondsUntilNextAttempt = a.SecondsUntilNextAttempt;
        }
 /// <summary>
 /// Creates a link in the database based on the IPAddress of the requestor and the RedirectUrl
 /// </summary>
 /// <param name="ipAddress"></param>
 /// <param name="redirectUrl"></param>
 /// <returns></returns>
 public static string AddLink(string ipAddress, string redirectUrl)
 {
     try
     {
         DbContext dbContext = new DbContext();
         var newLink = new Link();
         newLink.Id = Guid.NewGuid();
         newLink.DateCreated = DateTime.Now;
         newLink.RedirectUrl = redirectUrl;
         newLink.ShortCode = CreateUnusedShortCode();
         newLink.VisitCount = 0;
         dbContext.Links.InsertOnSubmit(newLink);
         dbContext.SubmitChanges();
         return newLink.ShortCode;
     }
     catch
     {
         throw new Exception();
     }
 }