//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Collections;
using CommunityServer.Components;

namespace CommunityServer.Spam.Rules
{
	/// <summary>
	/// Rates spam factor based on number of times posted from a particular ip address.
	/// </summary>
	public class IPSpamRule : SpamRule
	{
		private static readonly Guid ruleID = new Guid("5a104673-0745-435f-952c-fD18cd9f288c");
		private static readonly string resourceFile = "ControlPanelResources.xml";
		private static readonly int defaultPoints = 5;
		private static readonly int defaultThreshold = 1;
		private static readonly int defaultDuration = 60;
		private static readonly string defaultExclude = "000.000.000.000;127.0.0.1";

		public IPSpamRule()
		{
		}

		public override string Name
		{
			get { return ResourceManager.GetString("spam_IPRule_Name", resourceFile); }
		}

		public override string Description
		{
			get { return ResourceManager.GetString("spam_IPRule_Description", resourceFile); }
		}

		public override Guid RuleID
		{
			get { return ruleID; }
		}

		public override ArrayList GetAvailableSettings()
		{
			ArrayList settings = new ArrayList();
			settings.Add(new RuleSetting(ruleID, "points", ResourceManager.GetString("spam_IPRule_PointsDescription", resourceFile), defaultPoints.ToString()));
			settings.Add(new RuleSetting(ruleID, "threshold", ResourceManager.GetString("spam_IPRule_ThresholdDescription", resourceFile), defaultThreshold.ToString()));
			settings.Add(new RuleSetting(ruleID, "duration", ResourceManager.GetString("spam_IPRule_DurationDescription", resourceFile), defaultDuration.ToString()));
			settings.Add(new RuleSetting(ruleID, "exclude", ResourceManager.GetString("spam_IPRule_ExcludeDescription", resourceFile), defaultExclude, 8000));
			return settings;
		}

		public override int RatePost(Post post, CSPostEventArgs e)
		{
			// Verify that this spam rule should process this post
			if (IsExemptFromSpamRating(post, e))
				return 0;

			// If the current post is from an excluded address, don't rate it for spam
			string ipExcludeListString = GetSettingValue("exclude");
			if (ipExcludeListString == null)
				ipExcludeListString = defaultExclude;				
			string[] ipExcludeList = ipExcludeListString.Split(';');

			// Skip post if from ip to exclude
			foreach (string ipToExclude in ipExcludeList)
			{
				if (post.UserHostAddress == ipToExclude)
					return 0;
			}

			// Retrieve additional setting values
			int points = Globals.SafeInt(GetSettingValue("points"), defaultThreshold);
			int threshold = Globals.SafeInt(GetSettingValue("threshold"), defaultThreshold);
			int duration = Globals.SafeInt(GetSettingValue("duration"), defaultDuration);

			// Count posts from current ip (add current)
			int count = SpamRuleHelper.GetPostCountFromIPAddress(post.UserHostAddress, duration) + 1;

			// Score xxx points for each post above the threshold
			if (count > threshold)
				return (points * (count - threshold));

			return 0;
		}
	}
}
