using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Newtonsoft.Json.Utilities;

namespace Newtonsoft.Json.Linq.JsonPath
{
	internal class BooleanQueryExpression : QueryExpression
	{
		public object Left { get; set; }

		public object Right { get; set; }

		private IEnumerable<JToken> GetResult(JToken root, JToken t, object o)
		{
			JToken jtoken;
			if ((jtoken = o as JToken) != null)
			{
				return new JToken[] { jtoken };
			}
			List<PathFilter> list;
			if ((list = o as List<PathFilter>) != null)
			{
				return JPath.Evaluate(list, root, t, false);
			}
			return CollectionUtils.ArrayEmpty<JToken>();
		}

		public override bool IsMatch(JToken root, JToken t)
		{
			if (base.Operator == QueryOperator.Exists)
			{
				return this.GetResult(root, t, this.Left).Any<JToken>();
			}
			using (IEnumerator<JToken> enumerator = this.GetResult(root, t, this.Left).GetEnumerator())
			{
				if (enumerator.MoveNext())
				{
					IEnumerable<JToken> result = this.GetResult(root, t, this.Right);
					ICollection<JToken> collection = (result as ICollection<JToken>) ?? result.ToList<JToken>();
					do
					{
						JToken jtoken = enumerator.Current;
						foreach (JToken jtoken2 in collection)
						{
							if (this.MatchTokens(jtoken, jtoken2))
							{
								return true;
							}
						}
					}
					while (enumerator.MoveNext());
				}
			}
			return false;
		}

		private bool MatchTokens(JToken leftResult, JToken rightResult)
		{
			JValue jvalue;
			JValue jvalue2;
			if ((jvalue = leftResult as JValue) != null && (jvalue2 = rightResult as JValue) != null)
			{
				switch (base.Operator)
				{
				case QueryOperator.Equals:
					if (this.EqualsWithStringCoercion(jvalue, jvalue2))
					{
						return true;
					}
					break;
				case QueryOperator.NotEquals:
					if (!this.EqualsWithStringCoercion(jvalue, jvalue2))
					{
						return true;
					}
					break;
				case QueryOperator.Exists:
					return true;
				case QueryOperator.LessThan:
					if (jvalue.CompareTo(jvalue2) < 0)
					{
						return true;
					}
					break;
				case QueryOperator.LessThanOrEquals:
					if (jvalue.CompareTo(jvalue2) <= 0)
					{
						return true;
					}
					break;
				case QueryOperator.GreaterThan:
					if (jvalue.CompareTo(jvalue2) > 0)
					{
						return true;
					}
					break;
				case QueryOperator.GreaterThanOrEquals:
					if (jvalue.CompareTo(jvalue2) >= 0)
					{
						return true;
					}
					break;
				case QueryOperator.RegexEquals:
					if (BooleanQueryExpression.RegexEquals(jvalue, jvalue2))
					{
						return true;
					}
					break;
				}
			}
			else
			{
				QueryOperator @operator = base.Operator;
				if (@operator - QueryOperator.NotEquals <= 1)
				{
					return true;
				}
			}
			return false;
		}

		private static bool RegexEquals(object input, object pattern)
		{
			if (input.Type == JTokenType.String)
			{
				if (pattern.Type == JTokenType.String)
				{
					string text = (string)pattern.Value;
					int num = text.LastIndexOf('/');
					string text2 = text.Substring(1, num - 1);
					string text3 = text.Substring(num + 1);
					return Regex.IsMatch((string)input.Value, text2, MiscellaneousUtils.GetRegexOptions(text3));
				}
			}
			return false;
		}

		private bool EqualsWithStringCoercion(JValue value, JValue queryValue)
		{
			if (value.Equals(queryValue))
			{
				return true;
			}
			if (queryValue.Type != JTokenType.String)
			{
				return false;
			}
			string text = (string)queryValue.Value;
			string text2;
			switch (value.Type)
			{
			case JTokenType.Date:
			{
				using (StringWriter stringWriter = StringUtils.CreateStringWriter(64))
				{
					object value2;
					if ((value2 = value.Value) is DateTimeOffset)
					{
						DateTimeOffset dateTimeOffset = (DateTimeOffset)value2;
						DateTimeUtils.WriteDateTimeOffsetString(stringWriter, dateTimeOffset, DateFormatHandling.IsoDateFormat, null, CultureInfo.InvariantCulture);
					}
					else
					{
						DateTimeUtils.WriteDateTimeString(stringWriter, (DateTime)value.Value, DateFormatHandling.IsoDateFormat, null, CultureInfo.InvariantCulture);
					}
					text2 = stringWriter.ToString();
					goto IL_00DE;
				}
				break;
			}
			case JTokenType.Bytes:
				text2 = Convert.ToBase64String((byte[])value.Value);
				goto IL_00DE;
			case JTokenType.Guid:
			case JTokenType.TimeSpan:
				text2 = value.Value.ToString();
				goto IL_00DE;
			case JTokenType.Uri:
				text2 = ((Uri)value.Value).OriginalString;
				goto IL_00DE;
			}
			return false;
			IL_00DE:
			return string.Equals(text2, text, StringComparison.Ordinal);
		}
	}
}
