using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Scripting.Hosting;

namespace DaifugouWpf
{
    /// <summary>
    /// DLRを使ったスクリプトAI。
    /// </summary>
    public class ScripAi : Daifugou.IArtificialIntelligence
    {
        public ScripAi()
        {
        }

        ScriptScope scope;
        CompiledCode code;
        string filename;

        public void Init(string filename)
        {
            this.filename = filename;

            var ext = System.IO.Path.GetExtension(filename).Replace(".", "");

            if (string.IsNullOrEmpty(ext))
                throw new ArgumentException("拡張子がありません");

            ScriptRuntime runtime = ScriptRuntime.CreateFromConfiguration();
            runtime.LoadAssembly(typeof(Daifugou.Game).Assembly);
            runtime.LoadAssembly(typeof(System.Math).Assembly);
            runtime.LoadAssembly(typeof(System.Linq.Enumerable).Assembly);


            this.scope = runtime.CreateScope();
            var engine = runtime.GetEngine(ext);
            var script = engine.CreateScriptSourceFromFile(filename);
            this.code = script.Compile();

            // 事前に渡しておきたいものを登録
            this.scope.SetVariable("rand", new Random());
        }

        #region IArtificialIntelligence メンバ

        public IEnumerable<CardGame.Card> Play(IEnumerable<CardGame.Card> hand, IEnumerable<CardGame.Card> table, int rank, CardGame.Suit suit, Daifugou.Mode mode, bool revolution, Daifugou.History history)
        {
            // 引数の登録
            this.scope.SetVariable("hand", hand.ToArray());
            this.scope.SetVariable("table", table.ToArray());
            this.scope.SetVariable("rank", rank);
            this.scope.SetVariable("suit", suit);
            this.scope.SetVariable("mode", mode);
            this.scope.SetVariable("revolution", revolution);
            this.scope.SetVariable("history", history);

            // スクリプトの実行
            object obj = this.code.Execute(this.scope);
            var result = obj as System.Collections.IEnumerable;

            // 結果の取得
            // （IronPython は戻り値返せないみたいなんで、result 変数を経由して結果を受け取る）
            if (result == null)
            {
                if(!this.scope.TryGetVariable<System.Collections.IEnumerable>("result", out result))
                {
                    return null;
                }
            }

            if (result == null)
                return null;

            var r = result.Cast<CardGame.Card>().ToArray();

            return r;
        }

        #endregion
    }
}
