﻿#if !OVERRIDE_LUA
using System;
using System.Reflection;
using JLGames.RocketDriver.CSharp.Languages.Lua;
using UnityEngine;

namespace JLGames.RocketDriver.Actions.Languages.Lua
{
    public static class Lua
    {
        private static LuaTable m_Environment = null;

        public static LuaTable Environment => m_Environment;

        /// <summary>
        /// Static code block for initializing the Lua interpreter
        /// 静态代码块，用于初始化Lua解释器
        /// </summary>
        static Lua()
        {
            Init();
        }

        // Initialization

        /// <summary>
        /// Initialize the Lua interpreter
        /// 初始化Lua解释器
        /// </summary>
        public static void Init()
        {
            m_Environment = LuaInterpreter.CreateGlobalEnviroment();
#if UNITY_EDITOR
            m_Environment.Register("print", LuaUnityLib.UnityDebug);
            m_Environment.Register("warn", LuaUnityLib.UnityWarn);
#endif
        }

        /// <summary>
        /// Restart the Lua interpreter
        /// 重启Lua解释器
        /// </summary>
        public static void Restart()
        {
            m_Environment?.Reset();
            Init();
        }

        // Run

        #region Run

        /// <summary>
        /// Check if conditional expression is true
        /// 判断条件表达式是否为真
        /// </summary>
        /// <param name="luaCondition"></param>
        /// <param name="allowExceptions"></param>
        /// <returns></returns>
        public static bool IsTrue(string luaCondition, bool allowExceptions = false)
        {
            if (string.IsNullOrEmpty(luaCondition) || string.IsNullOrWhiteSpace(luaCondition)) return false;
            var luaCode = $"return {luaCondition}";
            return RunLua(luaCode, allowExceptions).AsBool;
        }

        /// <summary>
        /// Execute Lua script code
        /// 执行Lua脚本代码
        /// </summary>
        /// <param name="luaCode"></param>
        /// <param name="allowExceptions"></param>
        /// <returns></returns>
        public static LuaResult RunLua(string luaCode, bool allowExceptions = false)
        {
            return new LuaResult(RunLuaRaw(luaCode, allowExceptions));
        }

        /// <summary>
        /// Execute Lua script code
        /// 执行Lua脚本代码
        /// </summary>
        /// <param name="luaCode"></param>
        /// <param name="allowExceptions"></param>
        /// <returns></returns>
        public static LuaValue RunLuaRaw(string luaCode, bool allowExceptions = false)
        {
            if (string.IsNullOrEmpty(luaCode)) return null;

            try
            {
                return LuaInterpreter.Interpreter(luaCode, m_Environment);
            }
            catch (Exception)
            {
                if (allowExceptions) throw;
            }

            return null;
        }

        #endregion

        // Register

        #region Register

        /// <summary>
        /// Register functions to the Lua interpreter environment
        /// 注册函数到Lua解释器环境
        /// Only bool, string and double types are supported for function parameters
        /// 函数参数只支持bool、string、double三种类型
        /// </summary>
        /// <param name="funcName"></param>
        /// <param name="target"></param>
        /// <param name="method"></param>
        public static void RegisterFunction(string funcName, object target, MethodInfo method)
        {
            if (string.IsNullOrWhiteSpace(funcName)) return;
            if (m_Environment.ContainsKey(new LuaString(funcName))) return;

            m_Environment.RegisterMethodFunction(funcName, target, method);
        }

        /// <summary>
        /// Cancel the function registered in the Lua interpreter
        /// 取消Lua解释器中注册的函数
        /// </summary>
        /// <param name="funcName"></param>
        public static void UnregisterFunction(string funcName)
        {
            if (string.IsNullOrWhiteSpace(funcName)) return;
            m_Environment.SetNameValue(funcName, LuaNil.Nil);
        }

        #endregion
    }
}

#endif