﻿#region License

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#endregion

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using Gremlin.Net.Process.Traversal;

namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
{
    public class TraversalParser
    {
        private static readonly IDictionary<string, Func<GraphTraversalSource, ITraversal>> FixedTranslations = 
            new Dictionary<string, Func<GraphTraversalSource, ITraversal>>
            {
                { "g.V().fold().count(Scope.local)", g => g.V().Fold().Count(Scope.Local)},
                { "g.inject(10,20,null,20,10,10).groupCount(\"x\").dedup().as(\"y\").project(\"a\",\"b\").by().by(__.select(\"x\").select(__.select(\"y\")))", 
                    g => g.Inject<object>(10,20,null,20,10,10).GroupCount("x").Dedup().As("y").Project<object>("a","b").By().By(__.Select<int>("x").Select<object>(__.Select<int>("y")))}
            };

        private static readonly Regex RegexNumeric =
            new Regex(@"\d+(\.\d+)?(?:l|f)?", RegexOptions.Compiled | RegexOptions.IgnoreCase);

        private static readonly Regex RegexEnum = new Regex(@"\w+\.\w+", RegexOptions.Compiled);

        private static readonly Regex RegexIO = new Regex(@"IO.\w+", RegexOptions.Compiled);

        private static readonly Regex RegexWithOptions = new Regex(@"WithOptions.\w+", RegexOptions.Compiled);

        private static readonly Regex RegexParam = new Regex(@"\w+", RegexOptions.Compiled);
        
        private static readonly HashSet<Type> NumericTypes = new HashSet<Type>
        {
            typeof(int), typeof(long), typeof(double), typeof(float), typeof(short), typeof(decimal), typeof(byte)
        };

        internal static ITraversal GetTraversal(string traversalText, GraphTraversalSource g,
                                                IDictionary<string, object> contextParameterValues)
        {
            if (!FixedTranslations.TryGetValue(traversalText, out var traversalBuilder))
            {
                var tokens = ParseTraversal(traversalText);
                return GetTraversalFromTokens(tokens, g, contextParameterValues, traversalText);
            }
            return traversalBuilder(g);
        }

        internal static ITraversal GetTraversalFromTokens(IList<Token> tokens, GraphTraversalSource g,
                                                          IDictionary<string, object> contextParameterValues,
                                                          string traversalText)
        {
            object instance;
            Type instanceType;
            if (tokens[0].Name == "g")
            {
                instance = g;
                instanceType = g.GetType();
            }
            else if (tokens[0].Name == "__")
            {
                instance = null;
                instanceType = typeof(__);
            }
            else
            {
                throw BuildException(traversalText);
            }
            for (var i = 1; i < tokens.Count; i++)
            {
                var token = tokens[i];
                token.SetContextParameterValues(contextParameterValues);
                var name = GetCsharpName(token.Name);
                var methods = instanceType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
                    .Where(m => m.Name == name).ToList();
                var method = GetClosestMethod(methods, token.Parameters);
                if (method == null)
                {
                    throw new InvalidOperationException($"Traversal method '{tokens[i].Name}' not found for testing");
                }
                var parameterValues = BuildParameters(method, token, out var genericParameters);
                method = BuildGenericMethod(method, genericParameters, parameterValues);
                instance = method.Invoke(instance, parameterValues);
                instanceType = instance.GetType();
            }
            return (ITraversal) instance;
        }

        /// <summary>
        /// Find the method that supports the amount of parameters provided
        /// </summary>
        private static MethodInfo GetClosestMethod(IList<MethodInfo> methods, IList<ITokenParameter> tokenParameters)
        {
            if (methods.Count == 0)
            {
                return null;
            }
            if (methods.Count == 1)
            {
                return methods[0];
            }
            var ordered = methods.OrderBy(m => m.GetParameters().Length);
            if (tokenParameters.Count == 0)
            {
                return ordered.First();
            }
            MethodInfo lastMethod = null;
            var compatibleMethods = new Dictionary<int, MethodInfo>();
            foreach (var method in ordered)
            {
                var methodParameters = method.GetParameters();
                var requiredParameters = methodParameters.Length;
                if (requiredParameters > 0 && IsParamsArray(methodParameters.Last()))
                {
                    // Params array can be not provided
                    requiredParameters--;
                }
                if (tokenParameters.Count < requiredParameters)
                {
                    continue;
                }
                lastMethod = method;
                var matched = true;
                var exactMatches = 0;
                for (var i = 0; i < tokenParameters.Count; i++)
                {
                    if (methodParameters.Length <= i)
                    {
                        // The method contains less parameters (and no params array) than provided
                        matched = false;
                        break;
                    }
                    var methodParameter = methodParameters[i];
                    var tokenParameterType = tokenParameters[i].GetParameterType();
                    // Match either the same parameter type
                    matched = methodParameter.ParameterType == tokenParameterType;
                    if (matched)
                    {
                        exactMatches++;
                    }
                    else if (IsParamsArray(methodParameter))
                    {
                        matched = methodParameter.ParameterType == typeof(object[]) ||
                                  methodParameter.ParameterType.GetElementType() == tokenParameterType;
                        // The method has params array, no further parameters are going to be defined
                        break;
                    }
                    else
                    {
                        if (IsNumeric(methodParameter.ParameterType) && IsNumeric(tokenParameterType))
                        {
                            // Account for implicit conversion of numeric values as an exact match
                            exactMatches++;
                        }
                        else if (!methodParameter.ParameterType.GetTypeInfo().IsAssignableFrom(tokenParameterType))
                        {
                            // Not a match
                            break;
                        }
                        // Is assignable to the parameter type
                        matched = true;
                    }
                }
                if (matched)
                {
                    compatibleMethods[exactMatches] = method;
                }
            }
            // Attempt to use the method with the higher number of matches or the last one
            return compatibleMethods.OrderByDescending(kv => kv.Key).Select(kv => kv.Value).FirstOrDefault() ??
                   lastMethod;
        }

        private static bool IsNumeric(Type t) => NumericTypes.Contains(t);

        private static bool IsParamsArray(ParameterInfo methodParameter)
        {
            return methodParameter.IsDefined(typeof(ParamArrayAttribute), false);
        }

        private static MethodInfo BuildGenericMethod(MethodInfo method, IDictionary<string, Type> genericParameters,
                                                     object[] parameterValues)
        {
            if (!method.IsGenericMethod)
            {
                return method;
            }
            var genericArgs = method.GetGenericArguments();
            var types = new Type[genericArgs.Length];
            for (var i = 0; i < genericArgs.Length; i++)
            {
                var name = genericArgs[i].Name;
                Type type;
                if (!genericParameters.TryGetValue(name, out type))
                {
                    // Try to infer it from the name based on modern graph
                    type = ModernGraphTypeInformation.GetTypeArguments(method, parameterValues, i);
                }
                if (type == null)
                {
                    throw new InvalidOperationException(
                        $"Can not build traversal to test as '{method.Name}()' method is generic and type '{name}'" +
                         " can not be inferred");
                }
                types[i] = type;
            }
            return method.MakeGenericMethod(types);
        }

        private static object[] BuildParameters(MethodInfo method, Token token,
                                                out IDictionary<string, Type> genericParameterTypes)
        {
            var paramsInfo = method.GetParameters();
            var parameters = new object[paramsInfo.Length];
            genericParameterTypes = new Dictionary<string, Type>();

            for (var i = 0; i < paramsInfo.Length; i++)
            {
                var info = paramsInfo[i];
                object value = null;
                if (token.Parameters.Count > i)
                {
                    var tokenParameter = token.Parameters[i];
                    value =  tokenParameter.GetValue();
                    if (info.ParameterType.IsGenericParameter)
                    {
                        // We've provided a value for parameter of a generic type, we can infer the
                        // type of the generic argument based on the parameter.
                        // For example, in the case of `Constant<E2>(E2 value)`
                        // if we have the type of value we have the type of E2.
                        genericParameterTypes.Add(info.ParameterType.Name, tokenParameter.GetParameterType());
                    }
                    else if (IsParamsArray(info) && info.ParameterType.GetElementType().IsGenericParameter)
                    {
                        // Its a method where the type parameter comes from an params Array
                        // e.g., Inject<S>(params S[] value)
                        var type = tokenParameter.GetParameterType();
                        genericParameterTypes.Add(info.ParameterType.GetElementType().Name, type);

                        // Use a placeholder value
                        value = type.IsValueType ? Activator.CreateInstance(type) : new object();
                    }

                    if (info.ParameterType != tokenParameter.GetParameterType() && IsNumeric(info.ParameterType) &&
                        IsNumeric(tokenParameter.GetParameterType()))
                    {
                        // Numeric conversion
                        value = Convert.ChangeType(value, info.ParameterType);
                    }
                }

                if (IsParamsArray(info))
                {
                    // For `params type[] value` we should provide an empty array
                    if (value == null)
                    {
                        value = Array.CreateInstance(info.ParameterType.GetElementType(), 0);
                    }
                    else if (!value.GetType().IsArray)
                    {
                        // An array with the parameter values
                        // No more method parameters after this one
                        var elementType = info.ParameterType.GetElementType();

                        if (elementType.IsGenericParameter)
                        {
                            // The Array element type is generic, so we use type of the value to specify it
                            elementType = value.GetType();
                        }

                        var arr = Array.CreateInstance(elementType, token.Parameters.Count - i);
                        for (var j = 0; j < token.Parameters.Count - i; j++)
                        {
                            arr.SetValue(token.Parameters[i + j].GetValue(), j);
                        }
                        value = arr;
                    }
                }
                parameters[i] = value ?? GetDefault(info.ParameterType);
            }
            return parameters;
        }

        public static object GetDefault(Type type)
        {
            return type.GetTypeInfo().IsValueType ? Activator.CreateInstance(type) : null;
        }

        internal static string GetCsharpName(string part)
        {
            // Transform to PascalCasing and remove the parenthesis
            return char.ToUpper(part[0]) + part.Substring(1);
        }

        private static Exception BuildException(string traversalText)
        {
            return new InvalidOperationException($"Can not build a traversal to test from '{traversalText}'");
        }

        internal static IList<Token> ParseTraversal(string traversalText)
        {
            var index = 0;
            return ParseTokens(traversalText, ref index);
        }

        private static IList<Token> ParseTokens(string text, ref int i)
        {
            // Parser issue: quotes are not normalized
            text = text.Replace("\\\"", "\"");
            var result = new List<Token>();
            var startIndex = i;
            var parsing = ParsingPart.Name;
            var parameters = new List<ITokenParameter>();
            string name = null;
            while (i < text.Length)
            {
                switch (text[i])
                {
                    case '.':
                        if (parsing == ParsingPart.Name)
                        {
                            // The previous token was an object property, not a method
                            result.Add(new Token(text.Substring(startIndex, i - startIndex)));
                        }
                        startIndex = i + 1;
                        parameters = new List<ITokenParameter>();
                        parsing = ParsingPart.Name;
                        break;
                    case '(':
                    {
                        name = text.Substring(startIndex, i - startIndex);
                        parsing = ParsingPart.StartParameters;
                        // Start parsing from the next index
                        i++;
                        var param = ParseParameter(text, ref i);
                        if (param == null)
                        {
                            // The next character was a ')', empty params
                            // Evaluate the current position
                            continue;
                        }
                        parameters.Add(param);
                        break;
                    }
                    case ',' when parsing == ParsingPart.StartParameters && text.Length > i + 1 && text[i+1] != ' ':
                    case ' ' when parsing == ParsingPart.StartParameters && text.Length > i + 1 && text[i+1] != ' ' &&
                                  text[i+1] != ')':
                    {
                        i++;
                        var param = ParseParameter(text, ref i);
                        if (param == null)
                        {
                            // The next character was a ')', empty params
                            // Evaluate the current position
                            continue;
                        }
                        parameters.Add(param);
                        break;
                    }
                    case ',' when parsing != ParsingPart.StartParameters:
                    case ')' when parsing != ParsingPart.StartParameters:
                        // The current nested object already ended
                        if (parsing == ParsingPart.Name)
                        {
                            // The previous token was an object property, not a method and finished
                            result.Add(new Token(text.Substring(startIndex, i - startIndex)));
                        }
                        i--;
                        return result;
                    case ')':
                        parsing = ParsingPart.EndParameters;
                        result.Add(new Token(name, parameters));
                        break;
                }
                i++;
            }
            if (parsing == ParsingPart.Name)
            {
                // The previous token was an object property, not a method and finished
                result.Add(new Token(text.Substring(startIndex, i - startIndex)));
            }
            return result;
        }

        private static ITokenParameter ParseParameter(string text, ref int i)
        {
            var firstChar = text[i];
            while (char.IsWhiteSpace(firstChar))
            {
                firstChar = text[++i];
            }
            if (firstChar == ')')
            {
                return null;
            }
            if (firstChar == '"' || firstChar == '\'')
            {
                return StringParameter.Parse(text, firstChar, ref i);
            }
            if (char.IsDigit(firstChar))
            {
                return ParseNumber(text, ref i);
            }
            if (text.Length >= i + 3 && text.Substring(i, 3) == "__.")
            {
                var startIndex = i;
                var tokens = ParseTokens(text, ref i);
                return new StaticTraversalParameter(tokens, text.Substring(startIndex, i - startIndex));
            }
            if (text.Length >= i + 6 && text.Substring(i, 6) == "TextP.")
            {
                return new TextPParameter(ParseTokens(text, ref i));
            }
            if (text.Substring(i, 2).StartsWith("P."))
            {
                return new PParameter(ParseTokens(text, ref i));
            }
            var parameterText = text.Substring(i, text.IndexOf(')', i) - i);
            var separatorIndex = parameterText.IndexOf(',');
            if (separatorIndex >= 0)
            {
                parameterText = parameterText.Substring(0, separatorIndex);
            }
            parameterText = parameterText.Trim();
            if (parameterText == "")
            {
                return null;
            }
            if (parameterText == "true" || parameterText == "false")
            {
                i += parameterText.Length - 1;
                return LiteralParameter.Create(Convert.ToBoolean(parameterText));
            }
            if (parameterText == "null")
            {
                i += parameterText.Length - 1;
                return LiteralParameter.Create<object>(null);
            }
            if (RegexIO.IsMatch(parameterText))
            {
                i += parameterText.Length - 1;
                return new IOParameter(parameterText);
            }
            if (RegexWithOptions.IsMatch(parameterText))
            {
                i += parameterText.Length - 1;
                return new WithOptionsParameter(parameterText);
            }
            if (RegexEnum.IsMatch(parameterText))
            {
                i += parameterText.Length - 1;
                return new TraversalEnumParameter(parameterText);
            }
            if (RegexParam.IsMatch(parameterText))
            {
                i += parameterText.Length - 1;
                return new ContextBasedParameter(parameterText);
            }
            throw new NotSupportedException($"Parameter {parameterText} not supported");
        }
        
        private static ITokenParameter ParseNumber(string text, ref int i)
        {
            var match = RegexNumeric.Match(text, i);
            if (!match.Success)
            {
                throw new InvalidOperationException(
                    $"Could not parse numeric value from the beginning of {text.Substring(i)}");
            }
            var numericText = match.Value.ToUpper();
            i += match.Value.Length - 1;
            if (numericText.EndsWith("L"))
            {
                return LiteralParameter.Create(Convert.ToInt64(match.Value.Substring(0, match.Value.Length - 1)));
            }
            if (numericText.EndsWith("F"))
            {
                return LiteralParameter.Create(Convert.ToSingle(match.Value.Substring(0, match.Value.Length - 1),
                    CultureInfo.InvariantCulture));
            }
            if (match.Groups[1].Value != "")
            {
                // Captured text with the decimal separator
                return LiteralParameter.Create(Convert.ToDecimal(match.Value, CultureInfo.InvariantCulture));
            }
            return LiteralParameter.Create(Convert.ToInt32(match.Value));
        }
        
        private enum ParsingPart
        {
            Name,
            StartParameters,
            EndParameters
        }
    }
}
