using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using VRH.Common;
using VRH.Log4Pro.MultiLanguageManager;
using Vrh.XmlProcessing;

namespace Vrh.iScheduler.Report
{
    /// <summary>
    /// Az iScheduler-ben definiált interfész megvalósítása.
    /// </summary>
    public class SchedulerPlugin : Vrh.iScheduler.Interfaces.ISchedulerPlugin
    {
        private const string MESSAGEEMPTYPAR = "The parameter '{0}' is null or empty!";

        #region ISchedulerPlugin interface implementation

        #region Properties of implementation

        /// <summary>
        /// Az iScheduler.Report beépülő osztályának a neve.
        /// Értéke: "SchedulerReport"
        /// </summary>
        public string Name { get { return "SchedulerReport"; } }

        /// <summary>
        /// A végrehajtott metódusok során keletkező naplózási bejegyzések.
        /// Minden metódus indításakor törlődik.
        /// </summary>
        public List<string> LogEntries { get; private set; } = new List<string>();

        #endregion Properties of implementation

        #region Public methods of implementation

        #region CheckObjects public method
        /// <summary>
        /// Az <paramref name="objectList"/>-ben megadott csomagok létezésének
        /// ellenőrzése.
        /// </summary>
        /// <param name="xml">A Scheduler.Report xml paraméter fájl xmlparser kapcsolati sztringje.</param>
        /// <param name="objectList">Az ellenőrzendő report csomagok vesszővel elválasztva.</param>
        /// <param name="groupId">
        /// A SchedulerReport csoport azonosítója. 
        /// Opcionális, ha üres vagy null, akkor az <paramref name="xml"/> 
        /// paraméterfájlban megadott lesz érvényes.
        /// </param>
        /// <returns>
        /// Egy <c>CheckListJSON</c> elemekből álló lista.
        /// Ha nincs elem, akkor üres lista lesz az eredmény, nem null.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">Ha <paramref name="xml"/> null vagy üres.</exception>
        /// <exception cref="System.ApplicationException">Ha <paramref name="xml"/> nem létezik.</exception>
        public List<VRH.Common.CheckListJSON> CheckObjects(string xml, string objectList, string groupId = null)
        {
            #region DEBUG
#if DEBUG
            string thisfn = string.Concat(nameof(SchedulerPlugin), ".", nameof(CheckObjects), ": ");
            System.Diagnostics.Debug.WriteLine($"{thisfn}START");
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();
#endif
            #endregion DEBUG

            #region Paraméterek ellenőrzése
            if (string.IsNullOrWhiteSpace(xml))
            {
                throw new ArgumentNullException(nameof(xml), string.Format(MESSAGEEMPTYPAR, nameof(xml)));
            }
            #endregion Paraméterek ellenőrzése

            var resultList = new List<CheckListJSON>();
            //ha mégsincs ellenőrzendő, akkor üres listával tér vissza, nem hiba
            if (!string.IsNullOrWhiteSpace(objectList))
            {
                if (string.IsNullOrWhiteSpace(xml)) { xml = $"config={SRConstants.DEFAULT_CONFIGNAME};"; }
                var xmlc = new XmlConnection(xml);
                using (var srxp = new SchedulerReportXmlParser(xmlc, "", null, null, groupId))
                {
                    if (srxp.ErrorList.Any())
                    {
                        throw new ApplicationException(string.Join(Environment.NewLine, srxp.ErrorList));
                    }
                    using (var dbc = new SchedulerReportDbContext(srxp.ConnectionString))
                    {
                        string groupid = srxp.GroupId;
                        List<SelectListJSON> packages = dbc.SchedulerReportPackages
                                                                .Where(x => (groupid == SRConstants.Groups.All || x.GroupId == groupid))
                                                                .Select(s => new SelectListJSON() { Value = s.Name, Text = s.Description })
                                                                .ToList();

                        foreach (string id in objectList.Split(','))
                        {
                            SelectListJSON pack = packages.FirstOrDefault(x => x.Value == id);
                            resultList.Add(new CheckListJSON() { Value = id, Text = pack == null ? "" : pack.Text, Checked = pack != null });
                        }
                    } // using END
                } // using END
            }
            #region DEBUG
#if DEBUG
            sw.Stop();
            System.Diagnostics.Debug.WriteLine($"{thisfn}END Elapsed time = {sw.ElapsedMilliseconds}ms");
#endif
            #endregion DEBUG
            return resultList;
        }
        #endregion CheckObjects public method

        #region ListObjects public method
        /// <summary>
        /// Ütemezhető objektumok listája.
        /// </summary>
        /// <param name="xml">A Scheduler.Report xml paraméter fájl xmlparser connection stringje.</param>
        /// <param name="isActiveOnly">Csak az aktívnak jelölt elemek legyenek-e benne. Alapértelmezett értéke:true.</param>
        /// <param name="groupId">
        /// A SchedulerReport csoport azonosítója. 
        /// Opcionális, ha üres vagy null, akkor az <paramref name="xml"/> 
        /// paraméterfájlban megadott lesz érvényes.
        /// </param>
        /// <returns>
        /// Egy <c>SelectListJSON</c> elemekből álló lista.
        /// Ha nincs elem, akkor üres lista lesz az eredmény, nem null.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">Ha <paramref name="xml"/> null vagy üres.</exception>
        /// <exception cref="System.ApplicationException">Ha <paramref name="xml"/> nem létezik.</exception>
        public List<VRH.Common.SelectListJSON> ListObjects(string xml, bool isActiveOnly = true, string groupId = null)
        {
            #region DEBUG
#if DEBUG
            string thisfn = string.Concat(nameof(SchedulerPlugin), ".", nameof(ListObjects), ": ");
            System.Diagnostics.Debug.WriteLine($"{thisfn}START");
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();
#endif
            #endregion DEBUG

            #region Paraméterek ellenőrzése
            if (string.IsNullOrWhiteSpace(xml))
            {
                throw new ArgumentNullException(nameof(xml), string.Format(MESSAGEEMPTYPAR, nameof(xml)));
            }
            #endregion Paraméterek ellenőrzése

            var resultlist = new List<SelectListJSON>();
            if (string.IsNullOrWhiteSpace(xml)) { xml = $"config={SRConstants.DEFAULT_CONFIGNAME};"; }
            var xmlc = new XmlConnection(xml);
            using (var srxp = new SchedulerReportXmlParser(xmlc, "", null, null, groupId))
            {
                if (srxp.ErrorList.Any())
                {
                    throw new ApplicationException(string.Join(Environment.NewLine,srxp.ErrorList));
                }
                using (var dbc = new SchedulerReportDbContext(srxp.ConnectionString))
                {
                    string groupid = groupId ?? srxp.GroupId;
                    resultlist = dbc.SchedulerReportPackages
                                    .Where(x => (groupid == SRConstants.Groups.All || x.GroupId == groupid)
                                             && (!isActiveOnly || x.Active)
                                     )
                                    .Select(s => new SelectListJSON()
                                    {
                                        Value = s.Name,
                                        Text = s.Description + " (" + s.Name + ")",
                                        Disabled = !s.Active
                                    })
                                    .ToList();
                }
            }

            #region DEBUG
#if DEBUG
            sw.Stop();
            System.Diagnostics.Debug.WriteLine($"{thisfn}END Elapsed time = {sw.ElapsedMilliseconds}ms");
#endif
            #endregion DEBUG
            return resultlist;
        }
        #endregion ListObjects public method

        #region ListOperations public method
        /// <summary>
        /// Az ütemezésben kezdeményezhető műveletek listája.
        /// </summary>
        /// <returns>
        /// Egy <c>SelectListJSON</c> elemekből álló lista.
        /// Ha nincs elem, akkor üres lista lesz az eredmény, nem null.
        /// </returns>
        public List<SelectListJSON> ListOperations()
        {
            #region DEBUG
#if DEBUG
            string thisfn = string.Concat(nameof(SchedulerPlugin), ".", nameof(ListOperations), ": ");
            System.Diagnostics.Debug.WriteLine($"{thisfn}START");
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();
#endif
            #endregion DEBUG
            var resultlist = new List<SelectListJSON>();
            foreach (KeyValuePair<string, string> kvp in SRGlobal.Operations)
            {
                resultlist.Add(new SelectListJSON() { Value = kvp.Key, Text = kvp.Value });
            }
            #region DEBUG
#if DEBUG
            sw.Stop();
            System.Diagnostics.Debug.WriteLine($"{thisfn}END Elapsed time = {sw.ElapsedMilliseconds}ms");
#endif
            #endregion DEBUG
            return resultlist;
        }
        #endregion ListOperations public method

        #region TimedTask public method
        /// <summary>
        /// Amikor elérkezik az idő egy <c>OperationTime</c> pillanathoz, akkor
        /// az ütemező ezt fogja meghívni.
        /// </summary>
        /// <param name="xml">
        /// A Scheduler.Report xml paraméter fájl XmlParser kapcsolati sztringje.
        /// </param>
        /// <param name="lcid">
        /// A környezetre érvényes nyelvi kód. 
        /// Ha null, vagy üres, akkor az XML paraméterező fájlban beállított lesz az érvényes.
        /// </param>
        /// <param name="objectId">
        /// Melyik riportcsomaggal kapcsolatban történik a végrehajtás.
        /// Az az érték jön benne, mint ami a <c>ListObject.Value</c> 
        /// tulajdonságban lett küldve.
        /// </param>
        /// <param name="operationId">
        /// Melyik műveletet kell végrehajtani.
        /// Az az érték jön benne, mint ami a <c>ListOperations.Value</c> 
        /// tulajdonságban lett küldve.
        /// </param>
        /// <param name="timeStamp">
        /// Az ütemezés ideje (OperationTime mező értéke) 'yyyyMMddHHmmss' sztring formátumban.
        /// </param>
        /// <param name="groupId">
        /// A SchedulerReport csoport azonosítója. 
        /// Opcionális, ha üres vagy null, akkor az <paramref name="xml"/> 
        /// paraméterfájlban megadott lesz érvényes.
        /// </param>
        /// <returns>
        /// Egy <c>ReturnInfoJSON</c> objektum a message részében formázott html üzenettel.
        /// </returns>
        public ReturnInfoJSON ExecuteScheduledTask(string xml, string lcid, string objectId, string operationId, string timeStamp, string groupId = null)
        {
            string errorOccured = "Error occured when the TimedTask method is running.";
            try
            {
                #region DEBUG
#if DEBUG
                string thisfn = string.Concat(nameof(SchedulerPlugin), ".", nameof(ExecuteScheduledTask), ": ");
                System.Diagnostics.Debug.WriteLine($"{thisfn}START");
                var sw = new System.Diagnostics.Stopwatch();
                sw.Start();
#endif
                #endregion DEBUG
                this.LogEntries.Clear();
#if DEBUG
                this.LogEntries.Add($"*** Logs of the {thisfn} ***");
#endif
                this.LogEntries.Add($"TimedTask parameters: {nameof(xml)}={xml}, {nameof(lcid)}={lcid}, {nameof(objectId)}={objectId}, {nameof(operationId)}={operationId}, {nameof(timeStamp)}={timeStamp}, {nameof(groupId)}={groupId}");
                #region DEBUG
#if DEBUG
                System.Diagnostics.Debug.WriteLine($"{thisfn}{this.LogEntries.Last()}");
#endif
                #endregion DEBUG

                #region xml paraméter ürességének ellenőrzése
                if (string.IsNullOrWhiteSpace(xml))
                {
                    ThrEx(MESSAGEEMPTYPAR, nameof(xml));
                }
                #endregion xml paraméter ürességének ellenőrzése

                var rijson = new ReturnInfoJSON();
                if (string.IsNullOrWhiteSpace(xml)) { xml = $"config={SRConstants.DEFAULT_CONFIGNAME};"; }
                var xmlc = new XmlConnection(xml);
                using (var srxp = new SchedulerReportXmlParser(xmlc, null, lcid, null, groupId))
                {
                    this.LogEntries.Add($"Xml processing OK. XmlConnectionString/lcid/groupId=<{xml}/{lcid}/{groupId}>");
                    #region DEBUG
#if DEBUG
                    System.Diagnostics.Debug.WriteLine($"{thisfn}{this.LogEntries.Last()}");
#endif
                    #endregion DEBUG
                    var isrvars = new ScheduleReportVariables();

                    #region Paraméterek ellenőrzése

                    #region objectId, operationId, timeStamp ürességének ellenőrzése
                    string m_MessageEmptyPar = MultiLanguageManager.GetTranslation(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.TheParameterIsRequired), srxp.LCID);
                    if (string.IsNullOrWhiteSpace(objectId)) ThrEx(m_MessageEmptyPar, nameof(objectId));
                    if (string.IsNullOrWhiteSpace(operationId)) ThrEx(m_MessageEmptyPar, nameof(operationId));
                    if (string.IsNullOrWhiteSpace(timeStamp)) ThrEx(m_MessageEmptyPar, nameof(timeStamp));
                    this.LogEntries.Add($"Mandatory parameters '{nameof(objectId)}','{nameof(operationId)}','{nameof(timeStamp)}' have value check OK!");
                    #region DEBUG
#if DEBUG
                    System.Diagnostics.Debug.WriteLine($"{thisfn}{this.LogEntries.Last()}");
#endif
                    #endregion DEBUG
                    #endregion objectId, operationId, timeStamp ürességének ellenőrzése

                    #region TimeStamp ellenőrzése
                    timeStamp = timeStamp.Trim();
                    if (timeStamp.Length != 14)
                    {
                        ThrEx(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.TimeStampCorrectFormat), srxp.LCID);
                    }
                    if (!timeStamp.All(char.IsDigit))
                    {
                        ThrEx(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.TimeStampCorrectFormat), srxp.LCID);
                    }
                    isrvars[ScheduleReportVariables.DATESTAMP] = timeStamp.Substring(0, 8);
                    isrvars[ScheduleReportVariables.TIMESTAMP] = timeStamp.Substring(8);
                    this.LogEntries.Add($"TimeStamp is checked. DateStamp={isrvars[ScheduleReportVariables.DATESTAMP]}, TimeStamp={isrvars[ScheduleReportVariables.TIMESTAMP]}");
                    #region DEBUG
#if DEBUG
                    System.Diagnostics.Debug.WriteLine($"{thisfn}{this.LogEntries.Last()}");
#endif
					#endregion DEBUG
					#endregion TimeStamp ellenőrzése

					#endregion Paraméterek ellenőrzése

					#region operationid megjelenő név elkészítése
					string actionkeyortext;
					switch (operationId)
					{
						case SRConstants.Operations.EXECUTE_KEY: actionkeyortext = SRConstants.Operations.EXECUTE_TEXT; break;
						case SRConstants.Operations.FILEREPORT_KEY: actionkeyortext = SRConstants.Operations.FILEPORT_TEXT; break;
						case SRConstants.Operations.EXPORTDATA_KEY: actionkeyortext = SRConstants.Operations.EXPORTDATA_TEXT; break;
						default: actionkeyortext = operationId; break;
					}
					#endregion operationid megjelenő név elkészítése

					#region Válaszüzenet előkészítése
					string onerow = "<tr><td>{0}</td><td>{1}</td></tr>";
					string actionmessage = MultiLanguageManager.GetTranslation(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.ActionIsCompleted), srxp.LCID, actionkeyortext);

					rijson.ReturnMessage = string.Concat(actionmessage , "<br /><table>",
                        string.Format(
                            onerow,
                            MultiLanguageManager.GetTranslation(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.TitleReportId), srxp.LCID),
                            MultiLanguageManager.GetTranslation(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.TitleMessage), srxp.LCID)
                        )
                    );
                    #endregion Válaszüzenet előkészítése

                    using (var dbc = new SchedulerReportDbContext(srxp.ConnectionString))
                    {
                        this.LogEntries.Add($"Database connection OK. DBConnectionString:{srxp.ConnectionString}");
                        #region DEBUG
#if DEBUG
                        System.Diagnostics.Debug.WriteLine($"{thisfn}{this.LogEntries.Last()}");
#endif
                        #endregion DEBUG

                        #region Riportcsomag megkeresése és ellenőrzése
                        SchedulerReportPackage schedulerReportPackage = null;
                        IQueryable<SchedulerReportPackage> srps = dbc.SchedulerReportPackages
                                                                     .Where(x => x.GroupId == srxp.GroupId && x.Name == objectId)
                                                                     .Include(i => i.SchedulerReportPackageItems);
                        if (srps.Any())
                        {
                            if (srps.Count() > 1) { ThrEx(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.GroupIdObjectIdNotUnique), srxp.GroupId, objectId); }

                            schedulerReportPackage = srps.FirstOrDefault();
                            if (schedulerReportPackage.SchedulerReportPackageItems == null || !schedulerReportPackage.SchedulerReportPackageItems.Any())
                            {
                                ThrEx(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.ReportPackageEmpty), srxp.GroupId, objectId);
                            }
                        }
                        else { ThrEx(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.ReportPackageNotFound), srxp.GroupId, objectId); }
                        this.LogEntries.Add($"Reportpackage found. Name:{objectId},Group:{srxp.GroupId}.");
                        #region DEBUG
#if DEBUG
                        sw.Stop();
                        System.Diagnostics.Debug.WriteLine($"{thisfn}{this.LogEntries.Last()} Elapsed time: {sw.ElapsedMilliseconds}ms");
                        sw.Start();
#endif
                        #endregion DEBUG
                        #endregion Riportcsomag megkeresése és ellenőrzése

                        #region Riportcsomagból származó paraméterek beállítása (PCKNAME, ROLENAME)
                        isrvars[ScheduleReportVariables.PCKNAME] = schedulerReportPackage.Name;
                        isrvars[ScheduleReportVariables.ROLENAME] = schedulerReportPackage.RoleName;
                        //isrvars.ROLENAME.Value = "Admin";
                        #endregion Riportcsomagból származó paraméterek beállítása (PCKNAME, ROLENAME)

                        #region Címzett lista összeállítása

                        var userService = new Vrh.Membership.UserService();
                        this.LogEntries.Add("UserService initilization: Success.");

                        #region userGroup paraméter beállítása
                        bool useRoleGroup = false; // GetUserList első paramétere
                        var useRoleGroupPar = srxp.PackageExecute.UserListUrl.UrlParameters
                                                  .FirstOrDefault(x => x.Name.Equals("userolegroup", StringComparison.OrdinalIgnoreCase));
                        if (useRoleGroupPar != null)
                        {   // ha nem null, akkor az XML-ben adtak meg "usergroup" paramétert
                            if (bool.TryParse(isrvars.Substitution(useRoleGroupPar.Value), out bool ugp)) { useRoleGroup = ugp; }
                        }
                        this.LogEntries.Add($"The useRoleGroup(={useRoleGroup}) parameter setting is success.");
                        #region DEBUG
#if DEBUG
                        System.Diagnostics.Debug.WriteLine($"{thisfn}{this.LogEntries.Last()}");
#endif
                        #endregion DEBUG
                        #endregion userGroup paraméter beállítása
                        #region nameList paraméter beállítása
                        string nameList = null;
                        var nameListPar = srxp.PackageExecute.UserListUrl.UrlParameters
                                              .FirstOrDefault(x => x.Name.Equals("namelist", StringComparison.OrdinalIgnoreCase));
                        if (nameListPar != null)
                        {   // ha nem null, akkor az XML-ben adtak meg "namelist" paramétert
                            nameList = isrvars.Substitution(nameListPar.Value);
                        }
                        this.LogEntries.Add($"The nameList parameter setting is success. nameList={nameList}");
                        #endregion nameList paraméter beállítása

                        List<SelectListJSON> users = userService.GetUserList(useRoleGroup, nameList, true);
                        if (users == null || !users.Any())
                        {
                            ThrEx(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.ThereAreNoRecipients), srxp.LCID);
                        }
                        this.LogEntries.Add("The userService.GetUserList is success. Usernames:"+string.Join(",",users.Select(u=>u.Text)));

                        isrvars[ScheduleReportVariables.SENDTOEMAILLIST] = string.Join(",", users.Select(s => s.Text));
                        this.LogEntries.Add($"Email list = {isrvars[ScheduleReportVariables.SENDTOEMAILLIST]}.");
                        #region DEBUG
#if DEBUG
                        sw.Stop();
                        System.Diagnostics.Debug.WriteLine($"{thisfn}{this.LogEntries.Last()} Elapsed time: {sw.ElapsedMilliseconds}ms");
                        sw.Start();
#endif
                        #endregion DEBUG
                        #endregion Címzett lista összeállítása

                        List<string> successReportFiles = new List<string>();

						#region riportok/export file-ok elkészítése, file lista összetevése
						string messageSuccess = MultiLanguageManager.GetTranslation(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.ActionIsSuccessful), srxp.LCID, actionkeyortext);
						string messageNotSuccess = MultiLanguageManager.GetTranslation(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.ActionIsNotSuccessful), srxp.LCID, actionkeyortext);
						var reportService = new OneReport.ReportService("");
						var parameters = new Dictionary<string, string>();
						foreach (SchedulerReportPackageItem srpi in schedulerReportPackage.SchedulerReportPackageItems)
						{
							#region Paraméterek összeszedése és behelyettesítése

							isrvars[ScheduleReportVariables.REPORTNAME] = srpi.ReportId;
							isrvars[ScheduleReportVariables.LCID] = srpi.LCID;
							isrvars[ScheduleReportVariables.REPORTFORMAT] = srpi.ExportType;
							isrvars[ScheduleReportVariables.PARPRESET] = srpi.PresetId;

							#region ReportFilePath változó előállítása és ellenőrzése
							string rfp = isrvars.Substitution(srxp.PackageExecute.ReportFilePath);
							string direName = Path.GetDirectoryName(rfp);
							string fileName = Path.GetFileName(rfp);
							foreach (char c in System.IO.Path.GetInvalidPathChars()) { direName = direName.Replace(c, '_'); }//nem megengedett karakterek cseréje
							foreach (char c in System.IO.Path.GetInvalidFileNameChars()) { fileName = fileName.Replace(c, '_'); } //nem megengedett karakterek cseréje
                            if (!Directory.Exists(direName)) Directory.CreateDirectory(direName);
                            isrvars[ScheduleReportVariables.REPORTFILEPATH] = Path.Combine(direName, fileName);
                            #endregion ReportFilePath változó előállítása és ellenőrzése

                            string oneReportXML = null;
                            string oneReportId = srpi.ReportId;
                            string oneReportFormat = null;
                            string oneReportFile = isrvars[ScheduleReportVariables.REPORTFILEPATH];
                            string oneReportLCID = null;
                            foreach (var par in srxp.PackageExecute.RunReportUrl.UrlParameters)
                            {
                                if (par.Name.Equals(Vrh.OneReport.Constants.QParamNames.XML, StringComparison.OrdinalIgnoreCase))
                                {
                                    oneReportXML = isrvars.Substitution(par.Value);
                                    if (string.IsNullOrWhiteSpace(oneReportXML))
                                    {
                                        ThrEx(m_MessageEmptyPar, $"RunReportUrl.{Vrh.OneReport.Constants.QParamNames.XML}");
                                    }
                                }
                                //else if (par.Name.Equals(Vrh.OneReport.Constants.QParamNames.REPORTID, StringComparison.OrdinalIgnoreCase))
                                //{
                                //    oneReportId = isrvars.Substitution(par.Value);
                                //}
                                else if (par.Name.Equals(Vrh.OneReport.Constants.QParamNames.FORMAT, StringComparison.OrdinalIgnoreCase))
                                {
                                    oneReportFormat = isrvars.Substitution(par.Value);
                                }
                                else if (par.Name.Equals(Vrh.OneReport.Constants.QParamNames.FILE, StringComparison.OrdinalIgnoreCase))
                                {
                                    oneReportFile = isrvars.Substitution(par.Value);
                                }
                                else if (par.Name.Equals(Vrh.OneReport.Constants.QParamNames.LCID, StringComparison.OrdinalIgnoreCase))
                                {
                                    oneReportLCID = isrvars.Substitution(par.Value);
                                }
                                else
                                {
                                    parameters.Add(par.Name, isrvars.Substitution(par.Value));
                                }
                            }
                            this.LogEntries.Add($"ReportId=\"{oneReportId}\", XML=\"{oneReportXML}\", Format=\"{oneReportFormat}\", File=\"{oneReportFile}\", LCID=\"{oneReportLCID}\"");
                            #region DEBUG
#if DEBUG
                            sw.Stop();
                            System.Diagnostics.Debug.WriteLine($"{thisfn}ReportId={oneReportId} Set parameter elapsed time: {sw.ElapsedMilliseconds}ms");
                            sw.Start();
#endif
							#endregion DEBUG
							#endregion Paraméterek összeszedése és behelyettesítése

							#region Egy riport alapján a riport file, vagy az export file elkészítése
							string message="";
							try
							{
								switch (operationId)
								{
									case SRConstants.Operations.EXPORTDATA_KEY: reportService.Export(oneReportXML, oneReportFormat, oneReportFile, oneReportLCID, parameters); break;
									case SRConstants.Operations.FILEREPORT_KEY: reportService.ToFile(oneReportXML, oneReportFormat, oneReportFile, oneReportLCID, parameters); break;
									case SRConstants.Operations.EXECUTE_KEY: reportService.FileOrExport(oneReportXML, oneReportFormat, oneReportFile, oneReportLCID, parameters); break;
									case SRConstants.Operations.FILEOREXPORT_KEY: reportService.FileOrExport(oneReportXML, oneReportFormat, oneReportFile, oneReportLCID, parameters); break;
									default: throw new Exception($"Operation is not defined!");
								}
								this.LogEntries.Add($"ReportId={oneReportId} is successfully processed. Operation: {operationId}.");
								message = messageSuccess;
								successReportFiles.Add(oneReportFile);  //email attachments
							}
							catch (Exception ex)
							{
								rijson.ReturnValue = -1;
								this.LogEntries.Add($"ReportId={oneReportId} processing failed! Operation: {operationId}.");
								var errorList = VrhCommon.ErrorListBuilder(ex);
								this.LogEntries.AddRange(errorList);
								message = string.Concat(
									messageNotSuccess, VrhCommon.HTML_NEWLINE,
									MultiLanguageManager.GetTranslation(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.TitleMessage), srxp.LCID), ":", VrhCommon.HTML_NEWLINE,
									string.Join(VrhCommon.HTML_NEWLINE, errorList)
								);
#region DEBUG
#if DEBUG
								System.Diagnostics.Debug.WriteLine($"{thisfn}{message}{Environment.NewLine}{string.Join(Environment.NewLine, this.LogEntries)}");
								message += string.Concat(
									VrhCommon.HTML_NEWLINE,
									string.Join(VrhCommon.HTML_NEWLINE, this.LogEntries)
								);
#endif
#endregion DEBUG
							}
							rijson.ReturnMessage += string.Format(onerow, oneReportId, message);
							#endregion Egy riport alapján a riport file, vagy az export file elkészítése

						}
						#region DEBUG
#if DEBUG
						sw.Stop();
                        System.Diagnostics.Debug.WriteLine($"{thisfn}{this.LogEntries.Last()} Elapsed time: {sw.ElapsedMilliseconds}ms");
                        sw.Start();
#endif
                        #endregion DEBUG
                        rijson.ReturnMessage += "</table>";
						#endregion riportok/export file-ok elkészítése, file lista összetevése

						#region Riportok elküldése
						if (successReportFiles.Any())
                        {
                            isrvars[ScheduleReportVariables.FILEPATHLIST] = string.Join(",", successReportFiles);

                            #region Paraméterek összeszedése és behelyettesítése
                            var onp = new OneMessage.OneMessageParameters { AppPath = "" };
                            var parameterdictionary = srxp.PackageExecute.SendMessageUrl.UrlParameters
                                .Select(par=>new KeyValuePair<string,string>(par.Name, isrvars.Substitution(par.Value)))
                                .ToList();
                            onp = new OneMessage.OneMessageParameters(parameterdictionary); ;
                            this.LogEntries.Add($"OneMessage: Parameter processing is OK!");
                            #endregion Paraméterek összeszedése és behelyettesítése

                            #region Email elküldése
                            try
                            {
                                OneMessage.OneMessage oneMessage = new OneMessage.OneMessage(onp);
                                oneMessage.SendMessage();
                                this.LogEntries.Add($"OneMessage: Sending is OK!");
                                rijson.ReturnMessage += VrhCommon.HTML_NEWLINE
                                                      + MultiLanguageManager.GetTranslation(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.MailingIsSuccessful), srxp.LCID);
                            }
                            catch (Exception ex)
                            {
                                this.LogEntries.Add($"OneMessage: Sending is not OK!");
                                var errorList = VrhCommon.ErrorListBuilder(ex);
                                this.LogEntries.AddRange(errorList);
                                rijson.ReturnValue = -3;
                                rijson.ReturnMessage += string.Concat(
                                    VrhCommon.HTML_NEWLINE,
                                    MultiLanguageManager.GetTranslation(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.MailingIsNotSuccessful), srxp.LCID),
                                    VrhCommon.HTML_NEWLINE, "<i>",
                                    MultiLanguageManager.GetTranslation(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.TitleMessage), srxp.LCID), ":", VrhCommon.HTML_NEWLINE,
                                    string.Join(VrhCommon.HTML_NEWLINE, errorList), "</i>");
                            }
                            #region DEBUG
#if DEBUG
                            sw.Stop();
                            System.Diagnostics.Debug.WriteLine($"{thisfn}{this.LogEntries.Last()} Elapsed time: {sw.ElapsedMilliseconds}ms");
#endif
                            #endregion DEBUG
                            #endregion Email elküldése
                        }
                        else
                        {
                            rijson.ReturnValue = -2;
                            rijson.ReturnMessage += string.Concat(
                                VrhCommon.HTML_NEWLINE,
                                MultiLanguageManager.GetTranslation(typeof(SRWordCodes.iSchedulerReport.Operation.Messages.ThereAreNoSuccessfulPackages), srxp.LCID)
                            );
                        }
                        #endregion Riportok elküldése

                    }//using (iSchedulerDbContext dbc = new iSchedulerDbContext(constr)) VÉGE
                }
                #region DEBUG
#if DEBUG
                System.Diagnostics.Debug.WriteLine($"ReturnValue = {rijson.ReturnValue}");
                System.Diagnostics.Debug.WriteLine($"ReturnMessage = {rijson.ReturnMessage}");
                System.Diagnostics.Debug.WriteLine($"iSchedulerReport.Execute END {DateTime.Now}\n");
#endif
                #endregion DEBUG

                return rijson;
            }
            catch (Exception ex)
            {
                throw new ApplicationException(errorOccured,ex);
            }
        }
        #endregion TimedTask public method

        #endregion Public methods of implementation

        #endregion ISchedulerPlugin interface implementation


        #region Private methods (EmtpyCheck, ThrEx)

        #region ThrEx private methods
        /// <summary>
        /// Egy ApplicationException dobása a hibaüzenet megszerzése után.
        /// </summary>
        /// <param name="wordCodeType">Egy típus, mely a szókódot (WordCode) reprezentálja.</param>
        /// <param name="lcid">Nyelvi kód (Language Code ID)</param>
        /// <param name="pars">Objektumok listája, melyek behelyettesítésre kerülnek a <c>String.Format()</c> szabályai szerint.</param>
        protected void ThrEx(Type wordCodeType, string lcid, params object[] pars)
        {
            ThrEx(MultiLanguageManager.GetTranslation(wordCodeType,lcid), pars);
        }

        /// <summary>
        /// Egy ApplicationException dobása a hibaüzenet megszerzése után.
        /// </summary>
        /// <param name="messageFormat">Az üzenet maga, mely tartalmazhat string.Format szerinti hivatkozásokat.</param>
        /// <param name="pars">Objektumok listája, melyek behelyettesítésre kerülnek a <c>String.Format()</c> szabályai szerint.</param>
        protected void ThrEx(string messageFormat, params object[] pars)
        {
            throw new ApplicationException(string.Format(messageFormat, pars));
        }
        #endregion ThrEx private methods

        #endregion Private methods
    }
}
