//  
//  Task.cs
//  
//  Author:
//       Robert BRACCAGNI alias Gai-Luron <lfsgailuron@free.fr>
// 
//  Copyright (c) 2010 Gai-Luron
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
// 
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.



using System;
using System.Text;

namespace LFSLapper
{
	partial class LFSClient
	{
		void loopTask()
		{
			try
			{
				Task[] listTask = (Task[])Tasks.ToArray(typeof(Task));
				for (int i = 0; i < listTask.Length; i++)
				{
					Task currTask = listTask[i];
					if (currTask.IsToExecuteNow())
					{
						if (currTask.executed == false)
						{
							currTask.executed = true;
							newCfg.executeFunction(currTask.Command, null, null);
							if (currTask.IsOnceToExecuteOnly)
								currTask.toRemove = true;
						}
					}
					else
						currTask.executed = false;
				}
				for (int i = Tasks.Count - 1; i >= 0; i--)
				{
					if ((Tasks[i] as Task).toRemove)
						Tasks.RemoveAt(i);
				}
/*
				for (int i = 0; i < Tasks.Count; i++)
				{
					Task task = (Task)Tasks[i];
					if (task.IsToExecuteNow())
					{
						newCfg.executeFunction(task.Command, null, null);
						if (task.IsOnceToExecuteOnly)
							Tasks.RemoveAt(i--);
					}
				}
*/
			}
			catch (Exception ex)
			{

				myDebug.WriteLine("err", "Error on Task " + ex.ToString());
			}
		}
	}
    public class Task
    {
		public readonly string idTask;
        public readonly string Command;
        public readonly string Cron;
        public readonly bool IsOnceToExecuteOnly = true;
		public bool executed = false;
		public bool toRemove = false;

        int s = -1;
        int min = -1;
        int hr = -1;
        int day = -1;
        int dayOfWeek = -1;
        int mon = -1;
        int yr = -1;

		public Task(string idTask, string Command, DateTime DateTime)
        {
			this.idTask = idTask;
			this.Command = Command;

            s = DateTime.Second;
            min = DateTime.Minute;
            hr = DateTime.Hour;
            day = DateTime.Day;
            mon = DateTime.Month;
            yr = DateTime.Year;

            IsOnceToExecuteOnly = true;
        }

        public Task( string idTask, string Command, string CronSchedule )
        {
			this.idTask = idTask;
            this.Command = Command;
            this.Cron = CronSchedule;

            //parse CronSchedule
            System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"\d+|\*");
            System.Text.RegularExpressions.MatchCollection mc = regex.Matches(CronSchedule);

            if (!regex.IsMatch(CronSchedule) || mc.Count != 7)
                throw new Exception( "Error in RegisterScheduleAction " + Command + "in config file" );

            int val = 0;
            for (int i = 0; i < mc.Count; i++)
            {
                if (mc[i].Value == "*")
                {
                    val = -1;
                    IsOnceToExecuteOnly = false;
                }
                else
                    val = int.Parse(mc[i].Value);

                switch (i)
                {
                    case 0: this.s = val; break;
                    case 1: this.min = val; break;
                    case 2: this.hr = val; break;
                    case 3: this.dayOfWeek = val; break;
                    case 4: this.day = val; break;
                    case 5: this.mon = val; break;
                    case 6: this.yr = val; break;
                    default: throw new Exception("Too many fields in schedule");
                }
            }

        }

        bool Equals(DateTime dt)
        {
            return
                (dt.Year == yr || yr == -1) &&
                (dt.Month == mon || mon == -1) &&
                (dt.Day == day || day == -1) &&
                ((int)dt.DayOfWeek == dayOfWeek || dayOfWeek == -1) &&
                (dt.Hour == hr || hr == -1) &&
                (dt.Minute == min || min == -1) &&
                (dt.Second == s || s == -1);
        }

        public bool IsToExecuteNow()
        {
            return this.Equals(System.DateTime.Now);
        }
    }
}
