using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Aitex.Common.Util;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.RecipeCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;

namespace Venus_RT.Modules.PMs
{
    public class VenusRecipeFileContext : IRecipeFileContext
    {
        public string GetRecipeDefiniton(string chamberId)
        {
            try
            {
                string recipeSchema = PathManager.GetCfgDir() + @"\RecipeFormat.xml";

                XmlDocument xmlDom = new XmlDocument();
                xmlDom.Load(recipeSchema);

                bool epdInstalled = SC.ContainsItem("System.SetUp.EPDInstalled") && SC.GetValue<bool>($"System.SetUp.EPDInstalled");
                if (!epdInstalled)
                {
                    var nodeEndPoint =
                        xmlDom.SelectSingleNode(
                                string.Format(
                                    "/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='System.SetUp.EPDInstalled']"))
                            as XmlElement;
                    if (nodeEndPoint != null)
                    {
                        nodeEndPoint.ParentNode.RemoveChild(nodeEndPoint);
                    }
                }

                double rfPowerRange = SC.GetValue<double>($"{chamberId}.Rf.PowerRange");
                double rfPowerRangeBias = SC.GetValue<double>($"{chamberId}.BiasRf.PowerRange");
                bool rfEnablePulsing = SC.GetValue<bool>($"{chamberId}.Rf.EnablePulsingFunction");
                bool rfEnableBias = SC.GetValue<bool>($"{chamberId}.BiasRf.EnableBiasRF");

                var nodeRfPowerBias = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf.SetPower']")) as XmlElement;
                var nodeMatchModeBias = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf.SetMatchProcessMode']")) as XmlElement;
                var nodeMatchC1Bias = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf.SetMatchPositionC1']")) as XmlElement;
                var nodeMatchC2Bias = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf.SetMatchPositionC2']")) as XmlElement;
                var nodeRfPower = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='Rf.SetPower']")) as XmlElement;
                var nodeRfPowerBiasSoft = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf.SoftTolerance']")) as XmlElement;
                var nodeRfPowerBiasHard = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf.HardTolerance']")) as XmlElement;

                if (nodeRfPower != null)
                {
                    nodeRfPower.SetAttribute("Max", (int)rfPowerRange + "");
                }
                if (nodeRfPowerBias != null)
                {
                    nodeRfPowerBias.SetAttribute("Max", (int)rfPowerRangeBias + "");
                    if (!rfEnableBias)
                    {
                        nodeRfPowerBias.ParentNode.RemoveChild(nodeRfPowerBias);
                        nodeMatchModeBias.ParentNode.RemoveChild(nodeMatchModeBias);
                        nodeMatchC1Bias.ParentNode.RemoveChild(nodeMatchC1Bias);
                        nodeMatchC2Bias.ParentNode.RemoveChild(nodeMatchC2Bias);

                        nodeRfPowerBiasSoft?.ParentNode.RemoveChild(nodeRfPowerBiasSoft);
                        nodeRfPowerBiasHard?.ParentNode.RemoveChild(nodeRfPowerBiasHard);
                    }
                }
                if (!rfEnablePulsing)
                {
                    var node1 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='Rf.SetPulsingFrequency']")) as XmlElement;
                    if (node1 != null)
                        node1.ParentNode.RemoveChild(node1);

                    var node2 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='Rf.SetPulsingDuty']")) as XmlElement;
                    if (node2 != null)
                        node2.ParentNode.RemoveChild(node2);

                    var node3 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step/Item[@ControlName='PulsingMode']")) as XmlElement;
                    if (node3 != null)
                        node3.ParentNode.RemoveChild(node3);

                }

                string gas1Name = SC.GetStringValue($"{chamberId}.MfcGas1.GasName");
                bool gas1Enable = SC.GetValue<bool>($"{chamberId}.MfcGas1.Enable");
                int gas1N2Scale = SC.GetValue<int>($"{chamberId}.MfcGas1.MfcN2Scale");
                double gas1ScaleFactor = SC.GetValue<double>($"{chamberId}.MfcGas1.MfcScaleFactor");

                var nodeGas1 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas1']")) as XmlElement;
                var nodeGas1Soft = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas1.SoftTolerance']")) as XmlElement;
                var nodeGas1Hard = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas1.HardTolerance']")) as XmlElement;
                //if (nodeGas1 != null)
                //{
                //    if (!gas1Enable)
                //    {
                //        nodeGas1.ParentNode.RemoveChild(nodeGas1);
                //        nodeGas1Soft.ParentNode.RemoveChild(nodeGas1Soft);
                //        nodeGas1Hard.ParentNode.RemoveChild(nodeGas1Hard);
                //    }
                //    else
                //    {
                //        nodeGas1.SetAttribute("DisplayName", gas1Name);
                //        nodeGas1.SetAttribute("Max", (int)(gas1N2Scale * gas1ScaleFactor) + "");

                //        nodeGas1Soft.SetAttribute("DisplayName", $"{gas1Name} (Soft)(%)");
                //        nodeGas1Hard.SetAttribute("DisplayName", $"{gas1Name} (Hard)(%)");
                //    }
                //}

                //string gas2Name = SC.GetStringValue($"{chamberId}.MfcGas2.GasName");
                //bool gas2Enable = SC.GetValue<bool>($"{chamberId}.MfcGas2.Enable");
                //int gas2N2Scale = SC.GetValue<int>($"{chamberId}.MfcGas2.MfcN2Scale");
                //double gas2ScaleFactor = SC.GetValue<double>($"{chamberId}.MfcGas2.MfcScaleFactor");

                //var nodeGas2 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas2']")) as XmlElement;
                //var nodeGas2Soft = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas2.SoftTolerance']")) as XmlElement;
                //var nodeGas2Hard = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas2.HardTolerance']")) as XmlElement;
                //if (nodeGas2 != null)
                //{
                //    if (!gas2Enable)
                //    {
                //        nodeGas2.ParentNode.RemoveChild(nodeGas2);
                //        nodeGas2Soft.ParentNode.RemoveChild(nodeGas2Soft);
                //        nodeGas2Hard.ParentNode.RemoveChild(nodeGas2Hard);
                //    }
                //    else
                //    {
                //        nodeGas2.SetAttribute("DisplayName", gas2Name);
                //        nodeGas2.SetAttribute("Max", (int)(gas2N2Scale * gas2ScaleFactor) + "");

                //        nodeGas2Soft.SetAttribute("DisplayName", $"{gas2Name} (Soft)(%)");
                //        nodeGas2Hard.SetAttribute("DisplayName", $"{gas2Name} (Hard)(%)");
                //    }
                //}

                //string gas3Name = SC.GetStringValue($"{chamberId}.MfcGas3.GasName");
                //bool gas3Enable = SC.GetValue<bool>($"{chamberId}.MfcGas3.Enable");
                //int gas3N2Scale = SC.GetValue<int>($"{chamberId}.MfcGas3.MfcN2Scale");
                //double gas3ScaleFactor = SC.GetValue<double>($"{chamberId}.MfcGas3.MfcScaleFactor");

                //var nodeGas3 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas3']")) as XmlElement;
                //var nodeGas3Soft = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas3.SoftTolerance']")) as XmlElement;
                //var nodeGas3Hard = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas3.HardTolerance']")) as XmlElement;
                //if (nodeGas3 != null)
                //{
                //    if (!gas3Enable)
                //    {
                //        nodeGas3.ParentNode.RemoveChild(nodeGas3);
                //        nodeGas3Soft.ParentNode.RemoveChild(nodeGas3Soft);
                //        nodeGas3Hard.ParentNode.RemoveChild(nodeGas3Hard);
                //    }
                //    else
                //    {
                //        nodeGas3.SetAttribute("DisplayName", gas3Name);
                //        nodeGas3.SetAttribute("Max", (int)(gas3N2Scale * gas3ScaleFactor) + "");

                //        nodeGas3Soft.SetAttribute("DisplayName", $"{gas3Name} (Soft)(%)");
                //        nodeGas3Hard.SetAttribute("DisplayName", $"{gas3Name} (Hard)(%)");
                //    }
                //}


                //string gas4Name = SC.GetStringValue($"{chamberId}.MfcGas4.GasName");
                //bool gas4Enable = SC.GetValue<bool>($"{chamberId}.MfcGas4.Enable");
                //int gas4N2Scale = SC.GetValue<int>($"{chamberId}.MfcGas4.MfcN2Scale");
                //double gas4ScaleFactor = SC.GetValue<double>($"{chamberId}.MfcGas4.MfcScaleFactor");

                //var nodeGas4 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas4']")) as XmlElement;
                //var nodeGas4Soft = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas4.SoftTolerance']")) as XmlElement;
                //var nodeGas4Hard = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas4.HardTolerance']")) as XmlElement;
                //if (nodeGas4 != null)
                //{
                //    if (!gas4Enable)
                //    {
                //        nodeGas4.ParentNode.RemoveChild(nodeGas4);
                //        nodeGas4Soft.ParentNode.RemoveChild(nodeGas4Soft);
                //        nodeGas4Hard.ParentNode.RemoveChild(nodeGas4Hard);
                //    }
                //    else
                //    {
                //        nodeGas4.SetAttribute("DisplayName", gas4Name);
                //        nodeGas4.SetAttribute("Max", (int)(gas4N2Scale * gas4ScaleFactor) + "");

                //        nodeGas4Soft.SetAttribute("DisplayName", $"{gas4Name} (Soft)(%)");
                //        nodeGas4Hard.SetAttribute("DisplayName", $"{gas4Name} (Hard)(%)");
                //    }
                //}

                //string gas5Name = SC.GetStringValue($"{chamberId}.MfcGas5.GasName");
                //bool gas5Enable = SC.GetValue<bool>($"{chamberId}.MfcGas5.Enable");
                //int gas5N2Scale = SC.GetValue<int>($"{chamberId}.MfcGas5.MfcN2Scale");
                //double gas5ScaleFactor = SC.GetValue<double>($"{chamberId}.MfcGas5.MfcScaleFactor");

                //var nodeGas5 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas5']")) as XmlElement;
                //var nodeGas5Soft = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas5.SoftTolerance']")) as XmlElement;
                //var nodeGas5Hard = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas5.HardTolerance']")) as XmlElement;
                //if (nodeGas5 != null)
                //{
                //    if (!gas5Enable)
                //    {
                //        nodeGas5.ParentNode.RemoveChild(nodeGas5);
                //        nodeGas5Soft.ParentNode.RemoveChild(nodeGas5Soft);
                //        nodeGas5Hard.ParentNode.RemoveChild(nodeGas5Hard);
                //    }
                //    else
                //    {
                //        nodeGas5.SetAttribute("DisplayName", gas5Name);
                //        nodeGas5.SetAttribute("Max", (int)(gas5N2Scale * gas5ScaleFactor) + "");

                //        nodeGas5Soft.SetAttribute("DisplayName", $"{gas5Name} (Soft)(%)");
                //        nodeGas5Hard.SetAttribute("DisplayName", $"{gas5Name} (Hard)(%)");
                //    }
                //}
                //xmlDom.Save(recipeSchema);
                return xmlDom.OuterXml;
            }
            catch (Exception ex)
            {
                //LOG.Write(ex);
                return "";
            }
        }

        public IEnumerable<string> GetRecipes(string chamberId, bool includingUsedRecipe)
        {
            try
            {
                string recipePath = PathManager.GetRecipeDir() + chamberId + "\\";
                var di = new DirectoryInfo(recipePath);
                var fis = di.GetFiles("*.rcp", SearchOption.AllDirectories);
                var recipes = new List<string>();

                foreach (var fi in fis)
                {
                    string str = fi.FullName.Substring(recipePath.Length);
                    str = str.Substring(0, str.LastIndexOf('.'));
                    if (includingUsedRecipe || (!includingUsedRecipe && !str.Contains("HistoryRecipe\\")))
                    {
                        recipes.Add(str);
                    }
                }
                return recipes;
            }
            catch (Exception ex)
            {
                //LOG.Write(ex);
                return new List<string>();
            }
        }

        public void PostInfoEvent(string message)
        {
            EV.PostMessage("System", EventEnum.GeneralInfo, message);
        }

        public void PostWarningEvent(string message)
        {
            EV.PostMessage("System", EventEnum.DefaultWarning, message);
        }

        public void PostAlarmEvent(string message)
        {
            EV.PostMessage("System", EventEnum.DefaultAlarm, message);
        }

        public void PostDialogEvent(string message)
        {
            EV.PostNotificationMessage(message);
        }

        public void PostInfoDialogMessage(string message)
        {
            EV.PostMessage("System", EventEnum.GeneralInfo, message);

            EV.PostPopDialogMessage(EventLevel.Information, "System Information", message);
        }

        public void PostWarningDialogMessage(string message)
        {
            EV.PostMessage("System", EventEnum.GeneralInfo, message);

            EV.PostPopDialogMessage(EventLevel.Warning, "System Warning", message);
        }

        public void PostAlarmDialogMessage(string message)
        {
            EV.PostMessage("System", EventEnum.GeneralInfo, message);

            EV.PostPopDialogMessage(EventLevel.Alarm, "System Alarm", message);
        }

        public string GetRecipeTemplate(string chamberId)
        {
            string schema = GetRecipeDefiniton(chamberId);

            XmlDocument dom = new XmlDocument();

            dom.LoadXml(schema);

            XmlNode nodeTemplate = dom.SelectSingleNode("/Aitex/TableRecipeData");


            return nodeTemplate.OuterXml;
        }

        public bool EnableEdit(string recipeName)
        {
            //if (Singleton<RouteManager>.Instance.CheckRecipeUsedInJob(recipeName))
            //{
            //    EV.PostWarningLog("System", "Recipe is used in auto running jobs, can not be modified");
            //    return false;
            //}
            return true;
        }
    }
}