/* ==============================================================================
 * 功能描述:RevitCmdExecutor  
 * 创 建 者:Garrett
 * 创建日期:2019/4/16 11:46:37
 * ==============================================================================*/

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Newtonsoft.Json.Linq;

namespace Client.Start
{
    /// <summary>
    /// RevitCmdExecutor
    /// </summary>
    public class RevitCmdExecutor : IRevitCommandExcutor
    {
        public string ExecuteCmd(string revitCmd, string param, HashSet<string> filePathList)
        {
            string msg = null;
            try
            {
                //由revitCmd生成实体类
                //实体类传入参数、参考楼层列表
                //执行方法,返回执行结果 
                Console.WriteLine(DateTime.Now + " 准备执行命令:" + revitCmd);
                string fullPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "StartVisionSelector.exe");
                Process process = new Process();//AppDomain.CurrentDomain.BaseDirectory +
                process.StartInfo.FileName = fullPath;//执行的exe路径
                process.StartInfo.UseShellExecute = false;//不显示shell
                process.StartInfo.CreateNoWindow = true;//不创建窗口
                process.StartInfo.RedirectStandardInput = true;//打开流输入
                process.StartInfo.RedirectStandardOutput = true;//打开流输出
                process.StartInfo.RedirectStandardError = true;//打开错误流
                string resultFilePath = GetReusltFileName();
                string newParam = AddResultFileNameToParam(param, resultFilePath);
                Console.WriteLine(filePathList.First());
                //输入参数,多个参数使用空间分割,如果一个参数包含空格,使用""包括此参数
                //注意Json的传入格式
                process.StartInfo.Arguments = revitCmd + " " +
                                              "\"" + newParam + "\"" + " " +
                                              "\"" + filePathList.First() + "\"";
                process.Start();//执行
                //string msg = process.StandardOutput.ReadToEnd();//读取输出
                process.WaitForExit(21*60*1000);//等待执行完成
                //process.Close();//结束
                if(!process.HasExited)
                    process.Kill();
                msg = ReadResultString(resultFilePath);
                
                Console.WriteLine(DateTime.Now + " 命令执行完成:" + revitCmd);
#if !DEBUG
                //执行完成后,删除文件
                foreach (var f in filePathList)
                {
                    File.Delete(f);
                }
#endif
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message + "\r\n" + e.StackTrace);
            }

            return msg;
        }
        /// <summary>
        /// 将检查结果的保存位置添加到参数中
        /// </summary>
        /// <param name="param"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private string AddResultFileNameToParam(string param, string filePath)
        {

            JObject jObject = null;
            if (string.IsNullOrEmpty(param))
            {
                jObject = new JObject();
            }
            else
            {
                jObject = JObject.Parse(param);
            };
            string key = "ResultFileName";
            jObject.Add(new JProperty(key, filePath));
            return jObject.ToString().Replace("\"", "\\\"");
        }
        /// <summary>
        /// 生成 结果的保存文件名
        /// </summary>
        /// <returns></returns>
        private string GetReusltFileName()
        {
            string localPath = System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            string fileName = "Result_" + Guid.NewGuid().ToString() + ".txt";
            return Path.Combine(localPath, "RevitService", fileName);
        }
        /// <summary>
        /// 读取执行的结果,并清理结果文件
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        private string ReadResultString(string filePath)
        {
            Console.WriteLine(filePath);
            string str = "";

   if (File.Exists(filePath))
            {
                str = File.ReadAllText(filePath);
#if !DEBUG
                File.Delete(filePath);
#endif
            }          



            return str;
        }
    }
}