using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace IRaCIS.Core.Infrastructure.Extention
{
    /// 
    /// LINQ扩展方法
    /// 
    public static class LinqExtension
    {
        /// 
        /// 与连接
        /// 
        /// 类型
        /// 左条件
        /// 右条件
        /// 新表达式
        public static Expression> And(this Expression> left, Expression> right)
        {
            return CombineLambdas(left, right, ExpressionType.AndAlso);
        }
        /// 
        /// 或连接
        /// 
        /// 类型
        /// 左条件
        /// 右条件
        /// 新表达式
        public static Expression> Or(this Expression> left, Expression> right)
        {
            return CombineLambdas(left, right, ExpressionType.OrElse);
        }
        private static Expression> CombineLambdas(this Expression> left, Expression> right, ExpressionType expressionType)
        {
            var visitor = new SubstituteParameterVisitor
            {
                Sub =
                {
                    [right.Parameters[0]] = left.Parameters[0]
                }
            };
            Expression body = Expression.MakeBinary(expressionType, left.Body, visitor.Visit(right.Body));
            return Expression.Lambda>(body, left.Parameters[0]);
        }
    }
    internal class SubstituteParameterVisitor : ExpressionVisitor
    {
        public Dictionary Sub = new Dictionary();
        protected override Expression VisitParameter(ParameterExpression node)
        {
            return Sub.TryGetValue(node, out var newValue) ? newValue : node;
        }
    }
}