using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;

namespace InABox.Core
{
    internal static class ArrayFunctions
    {
        public const string GROUP = "Array";

        public static void Register()
        {
            CoreExpression.RegisterFunction("Array", "Create a new array, with the given type and length.", GROUP, new[]
            {
                "string type", "int length"
            }, (p, v, c) =>
            {
                var type = ConvertType(p[0].Evaluate<string>(v));
                var length = p[1].Evaluate<int>(v);
                return Array.CreateInstance(type, length);
            });
        }

        private static readonly Dictionary<string, Type> _types = new Dictionary<string, Type>()
        {
            { "sbyte", typeof(sbyte) },
            { "byte", typeof(byte) },
            { "short", typeof(short) },
            { "ushort", typeof(ushort) },
            { "int", typeof(int) },
            { "uint", typeof(uint) },
            { "long", typeof(long) },
            { "ulong", typeof(ulong) },

            { "float", typeof(float) },
            { "double", typeof(double) },
            { "decimal", typeof(decimal) },

            { "bool", typeof(bool) },
            { "char", typeof(char) },
            { "string", typeof(string) },

            { "TimeSpan", typeof(TimeSpan) },
            { "DateTime", typeof(DateTime) },
        };

        public static bool TryConvertType(string str, [NotNullWhen(true)] out Type? type)
        {
            if(_types.TryGetValue(str, out type)) return true;
            type = Type.GetType(str);
            if (type != null) return true;
            return false;
        }

        public static Type ConvertType(string str)
        {
            if(TryConvertType(str, out var type)) return type;
            throw new Exception($"Invalid type {str}");
        }
    }
}
