<commit_before>﻿// Copyright (c) <NAME>. All rights reserved. See license.txt in the project root for license information.

namespace Remote.Linq
{
    using Aqua.Dynamic;
    using Aqua.TypeSystem;
    using System;
    using System.ComponentModel;
    using RemoteLinq = Remote.Linq.Expressions;
    using SystemLinq = System.Linq.Expressions;

    [EditorBrowsable(EditorBrowsableState.Never)]
    public static partial class ExpressionTranslator
    {
        private sealed class ResultWrapperExpression : SystemLinq.Expression
        {
            public ResultWrapperExpression(RemoteLinq.Expression result, Type type)
            {
                Result = result;
                Type = type;
            }

            public RemoteLinq.Expression Result { get; }

            public override Type Type { get; }

            public override bool CanReduce => false;

            public override SystemLinq.ExpressionType NodeType => (SystemLinq.ExpressionType)(-1);

            protected override SystemLinq.Expression Accept(SystemLinq.ExpressionVisitor visitor) => throw Exception;

            protected override SystemLinq.Expression VisitChildren(SystemLinq.ExpressionVisitor visitor) => throw Exception;

            public override SystemLinq.Expression Reduce() => throw Exception;

            private static Exception Exception => throw new RemoteLinqException($"{nameof(ResultWrapperExpression)} is meant for internal usage and must not be exposed externally.");
        }

        // TODO: make private and use as default
        public static IExpressionToRemoteLinqContext NoMappingContext => new NoMappingContextImpl();

        private sealed class NoMappingContextImpl : IExpressionToRemoteLinqContext, IDynamicObjectMapper
        {
            public ITypeInfoProvider TypeInfoProvider => new TypeInfoProvider();

            public Func<object, bool> NeedsMapping => _ => false;

            public IDynamicObjectMapper ValueMapper => this;

            public Func<SystemLinq.Expression, bool>? CanBeEvaluatedLocally => _ => false;

            object? IDynamicObjectMapper.Map(DynamicObject? obj, Type? targetType) => throw NotSupportedException;

            DynamicObject? IDynamicObjectMapper.MapObject(object? obj, Func<Type, bool>? setTypeInformation) => throw NotSupportedException;

            private NotSupportedException NotSupportedException => new NotSupportedException("operation must not be called as no value mapping should occure");
        }

        /// <summary>
        /// Translates a given expression into a remote linq expression.
        /// </summary>
        public static RemoteLinq.Expression ToRemoteLinqExpression(this SystemLinq.Expression expression, IExpressionToRemoteLinqContext? context = null)
            => new SystemToRemoteLinqTranslator(context ?? ExpressionTranslatorContext.Default).ToRemoteExpression(expression);

        /// <summary>
        /// Translates a given expression into a remote linq expression.
        /// </summary>
        [Obsolete("Method will be removed in futur version, use overload instaed.")]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public static RemoteLinq.Expression ToRemoteLinqExpression(this SystemLinq.Expression expression, ITypeInfoProvider? typeInfoProvider, Func<SystemLinq.Expression, bool>? canBeEvaluatedLocally = null)
            => ToRemoteLinqExpression(expression, GetExpressionTranslatorContextOrNull(typeInfoProvider, canBeEvaluatedLocally));

        /// <summary>
        /// Translates a given lambda expression into a remote linq expression.
        /// </summary>
        public static RemoteLinq.LambdaExpression ToRemoteLinqExpression(this SystemLinq.LambdaExpression expression, IExpressionToRemoteLinqContext? context = null)
        {
            var lambdaExpression = new SystemToRemoteLinqTranslator(context ?? ExpressionTranslatorContext.Default).ToRemoteExpression(expression);
            return (RemoteLinq.LambdaExpression)lambdaExpression;
        }

        /// <summary>
        /// Translates a given lambda expression into a remote linq expression.<commit_msg>completing NoMappingContext for two-way translation<commit_after>﻿// Copyright (c) <NAME>. All rights reserved. See license.txt in the project root for license information.

namespace Remote.Linq
{
    using Aqua.Dynamic;
    using Aqua.TypeSystem;
    using System;
    using System.ComponentModel;
    using RemoteLinq = Remote.Linq.Expressions;
    using SystemLinq = System.Linq.Expressions;

    [EditorBrowsable(EditorBrowsableState.Never)]
    public static partial class ExpressionTranslator
    {
        private sealed class ResultWrapperExpression : SystemLinq.Expression
        {
            public ResultWrapperExpression(RemoteLinq.Expression result, Type type)
            {
                Result = result;
                Type = type;
            }

            public RemoteLinq.Expression Result { get; }

            public override Type Type { get; }

            public override bool CanReduce => false;

            public override SystemLinq.ExpressionType NodeType => (SystemLinq.ExpressionType)(-1);

            protected override SystemLinq.Expression Accept(SystemLinq.ExpressionVisitor visitor) => throw Exception;

            protected override SystemLinq.Expression VisitChildren(SystemLinq.ExpressionVisitor visitor) => throw Exception;

            public override SystemLinq.Expression Reduce() => throw Exception;

            private static Exception Exception => throw new RemoteLinqException($"{nameof(ResultWrapperExpression)} is meant for internal usage and must not be exposed externally.");
        }

        /// <summary>
        /// Gets an expression translator context that does not perform any value transformation other than expression and type information.
        /// </summary>
        /// <remarks>
        /// This context is typically used for in-memory translation and processing that does not include serialization of expressions.
        /// </remarks>
        public static IExpressionTranslatorContext NoMappingContext => new NoMappingContextImpl();

        private sealed class NoMappingContextImpl : IExpressionTranslatorContext, IDynamicObjectMapper
        {
            public ITypeInfoProvider TypeInfoProvider => new TypeInfoProvider();

            public Func<object, bool> NeedsMapping => _ => false;

            public IDynamicObjectMapper ValueMapper => this;

            public Func<SystemLinq.Expression, bool>? CanBeEvaluatedLocally => _ => false;

            object? IDynamicObjectMapper.Map(DynamicObject? obj, Type? targetType) => throw NotSupportedException;

            DynamicObject? IDynamicObjectMapper.MapObject(object? obj, Func<Type, bool>? setTypeInformation) => throw NotSupportedException;

            public ITypeResolver TypeResolver => Aqua.TypeSystem.TypeResolver.Instance;

            private NotSupportedException NotSupportedException => new NotSupportedException("Operation must not be called as no value mapping should occure.");
        }

        /// <summary>
        /// Translates a given expression into a remote linq expression.
        /// </summary>
        public static RemoteLinq.Expression ToRemoteLinqExpression(this SystemLinq.Expression expression, IExpressionToRemoteLinqContext? context = null)
            => new SystemToRemoteLinqTranslator(context ?? ExpressionTranslatorContext.Default).ToRemoteExpression(expression);

        /// <summary>
        /// Translates a given expression into a remote linq expression.
        /// </summary>
        [Obsolete("Method will be removed in futur version, use overload instaed.")]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public static RemoteLinq.Expression ToRemoteLinqExpression(this SystemLinq.Expression expression, ITypeInfoProvider? typeInfoProvider, Func<SystemLinq.Expression, bool>? canBeEvaluatedLocally = null)
            => ToRemoteLinqExpression(expression, GetExpressionTranslatorContextOrNull(typeInfoProvider, canBeEvaluatedLocally));

        /// <summary>
        /// Translates a given lambda expression into a remote linq expression.
        /// </summary>
        public static RemoteLinq.LambdaExpression ToRemoteLinqExpression(this SystemLinq.LambdaExpression expression, IExpressionToRemoteLinqContext? context = null)
        {
            var lambdaExpression = new SystemToRemoteLinqTranslator(context ?? ExpressionTranslatorContext.Default).ToRemoteExpression(expression);
            return (RemoteLinq.LambdaExpression)lambdaExpression;
        }

        /// <summary>
        /// Translates a given lambda expression into a remote linq expression.
{'fraction_non_alphanumeric': 0.07352941176470588, 'fraction_numerical': 0.00022977941176470588, 'mean_word_length': 3.1690613026819925, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 68, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '354349', 'n_tokens_mistral': 1955, 'n_tokens_neox': 1973, 'n_words': 591}