public static int AddNewSchedule(Schedule objSchedule)
 {
     int id = 0;
     List<KeyValuePair<string, object>> ParaMeterCollection = new List<KeyValuePair<string, object>>();
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@ScheduleName", objSchedule.ScheduleName));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@FullNameSpace", objSchedule.FullNamespace));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@StartDate", objSchedule.StartDate));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@EndDate", objSchedule.EndDate));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@StartHour", objSchedule.StartHour));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@StartMin", objSchedule.StartMin));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@RepeatWeeks", objSchedule.RepeatWeeks));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@RepeatDays", objSchedule.RepeatDays));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@WeekOfMonth", objSchedule.WeekOfMonth));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@EveryHour", objSchedule.EveryHours));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@EveryMin", objSchedule.EveryMin));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@ObjectDependencies", objSchedule.ObjectDependencies));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@RetryTimeLapse", objSchedule.RetryTimeLapse));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@RetryFrequencyUnit", objSchedule.RetryFrequencyUnit));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@AttachToEvent", objSchedule.AttachToEvent));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@CatchUpEnabled", objSchedule.CatchUpEnabled));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@Servers", objSchedule.Servers));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@IsEnable", objSchedule.IsEnable));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@RunningMode", (int)objSchedule.RunningMode));
     ParaMeterCollection.Add(new KeyValuePair<string, object>("@AssemblyFileName", objSchedule.AssemblyFileName));
     try
     {
         SQLHandler sagesql = new SQLHandler();
         id = sagesql.ExecuteNonQuery("usp_SchedulerAddJob", ParaMeterCollection, "@ScheduleID");
     }
     catch (Exception)
     {
         throw;
     }
     return id;
 }
        public static Schedule AddNewSchedule(Schedule objSchedule)
        {
            try
            {
                objSchedule.ScheduleID = SchedulerDataProvider.AddNewSchedule(objSchedule);

                //  RunScheduleItemNow(objSchedule);
            }
            catch (Exception e)
            {
                ErrorLogger.log(objSchedule, e, "AddNewSchedule");
                string fileName = objSchedule.AssemblyFileName;
                string filepath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, "bin\\" + fileName);
                DeleteFile(filepath);
                throw;
            }

            return objSchedule;
        }
        public static void log(Schedule schedule, Exception e, string methodName)
        {
            string location = HostingEnvironment.ApplicationPhysicalPath; //HostingEnvironment.ApplicationPhysicalPath
            string fileDirectory = Path.Combine(location, "ErrorLog");
            if (!Directory.Exists(fileDirectory))
            {
                Directory.CreateDirectory(fileDirectory);
            }
            string path = fileDirectory + "/SchedularExceptionLog.txt";

            using (StreamWriter writer = new StreamWriter(path, true))
            {
                lock (obj)
                {
                    writer.WriteLine(schedule.FullNamespace + "----- CurrentDate:" + DateTime.Now + "-----EndDate" + schedule.EndDate);
                    writer.WriteLine("Error Message" + e.Message.ToString() + "-----Error Source" + e.Source.ToString() + "-----Target Site" + e.TargetSite.ToString());
                    writer.WriteLine("Method Name :-" + methodName + "----------------------------------------------------------------------------------");
                }
            }

        }
        public static void UpdateSchedule(Schedule objSchedule)
        {
            List<KeyValuePair<string, object>> ParaMeterCollection = new List<KeyValuePair<string, object>>();
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@ScheduleName", objSchedule.ScheduleName));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@ScheduleID", objSchedule.ScheduleID));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@StartDate", Convert.ToDateTime(objSchedule.StartDate)));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@EndDate", Convert.ToDateTime(objSchedule.EndDate)));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@StartHour", objSchedule.StartHour));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@StartMin", objSchedule.StartMin));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@RepeatWeeks", objSchedule.RepeatWeeks));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@RepeatDays", objSchedule.RepeatDays));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@WeekOfMonth", objSchedule.WeekOfMonth));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@EveryHour", objSchedule.EveryHours));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@EveryMin", objSchedule.EveryMin));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@ObjectDependencies", objSchedule.ObjectDependencies));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@RetryTimeLapse", objSchedule.RetryTimeLapse));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@RetryFrequencyUnit", objSchedule.RetryFrequencyUnit));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@AttachToEvent", objSchedule.AttachToEvent));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@CatchUpEnabled", objSchedule.CatchUpEnabled));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@Servers", objSchedule.Servers));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@IsEnable", objSchedule.IsEnable));
            ParaMeterCollection.Add(new KeyValuePair<string, object>("@RunningMode", (int)objSchedule.RunningMode));

            try
            {
                SQLHandler sagesql = new SQLHandler();
                sagesql.ExecuteNonQuery("usp_ScheduleUpdate", ParaMeterCollection);

            }
            catch (Exception)
            {

                throw;
            }


        }
        public ScheduleHistory(Schedule objSchedule)
        {
            this.AttachToEvent = objSchedule.AttachToEvent;
            this.CatchUpEnabled = objSchedule.CatchUpEnabled;
            this.EveryMin = objSchedule.EveryMin;
            this.EveryHours = objSchedule.EveryHours;
            this.RunningMode = objSchedule.RunningMode;
            this.NextStart = objSchedule.NextStart;
            this.ObjectDependencies = objSchedule.ObjectDependencies;
            this.ProcessGroup = objSchedule.ProcessGroup;
            //this.RetainHistoryNum = objSchedule.RetainHistoryNum;
            this.RetryTimeLapse = objSchedule.RetryTimeLapse;
            this.RetryFrequencyUnit = objSchedule.RetryFrequencyUnit;
            this.ScheduleID = objSchedule.ScheduleID;
            //this.ScheduleSource = objSchedule.ScheduleSource;
            this.ThreadID = objSchedule.ThreadID;
            //this.TimeLapse = objSchedule.TimeLapse;
            //this.TimeLapseMeasurement = objSchedule.TimeLapseMeasurement;
            this.RepeatDays = objSchedule.RepeatDays;
            this.StartDate = objSchedule.StartDate;
            this.StartHour = objSchedule.StartHour;
            this.StartMin = objSchedule.StartMin;
            this.EndDate = objSchedule.EndDate;
            this.IsEnable = objSchedule.IsEnable;
            this.FullNamespace = objSchedule.FullNamespace;
            this.Servers = objSchedule.Servers;
            this.ScheduleName= objSchedule.ScheduleName;
            this.ScheduleHistoryID = null;
            this.HistoryStartDate = null;
            this.HistoryEndDate = null;
            this.Status = null;
            this.ReturnText = string.Empty;
            this.Server = string.Empty;
           

        }
        public SchedularView(Schedule objSchedule)
        {
            this.ScheduleID = objSchedule.ScheduleID;

            this.AttachToEvent = objSchedule.AttachToEvent;
            this.CatchUpEnabled = objSchedule.CatchUpEnabled;
            this.EveryMin = (short)objSchedule.EveryMin;
            this.NextStart = Convert.ToDateTime(objSchedule.NextStart);
            this.ObjectDependencies = objSchedule.ObjectDependencies;
            this.RetryTimeLapse = objSchedule.RetryTimeLapse;
            this.RetryFrequencyUnit = objSchedule.RetryFrequencyUnit;
            this.RepeatDays = objSchedule.RepeatDays;
            this.RepeatWeeks = (short)objSchedule.RepeatWeeks;
            this.RunningMode = (short)objSchedule.RunningMode;
            this.WeekOfMonth = objSchedule.WeekOfMonth;


            //this.TimeLapse = objSchedule.TimeLapse;
            //this.TimeLapseMeasurement = objSchedule.TimeLapseMeasurement;
            this.StartDate = Convert.ToDateTime(objSchedule.StartDate);
            this.StartHour = (short)objSchedule.StartHour;
            this.StartMin = (short)objSchedule.StartMin;
            this.EndDate = Convert.ToDateTime(objSchedule.EndDate);
            this.IsEnable = objSchedule.IsEnable;
            this._FullNameSpace = objSchedule.FullNamespace;
            this.Servers = objSchedule.Servers;
            this.ScheduleName = objSchedule.ScheduleName;



        }
        public static List<Schedule> GetTasks()
        {
            List<Schedule> lstTasks = new List<Schedule>();
            string StoredProcedureName = "usp_SchedulesGetCurrent";
            SqlDataReader SQLReader = null;
            SqlConnection SQLConn;
            using (SQLConn = new SqlConnection(SystemSetting.SageFrameConnectionString))
            {
                try
                {
                    SqlCommand SQLCmd = new SqlCommand();
                    SQLCmd.Connection = SQLConn;
                    SQLCmd.CommandText = StoredProcedureName;
                    SQLCmd.CommandType = CommandType.StoredProcedure;
                    SQLConn.Open();
                    SQLReader = SQLCmd.ExecuteReader();

                    while (SQLReader.Read())
                    {
                        Schedule obj = new Schedule();
                        obj.ScheduleName = SQLReader["ScheduleName"].ToString();
                        obj.ScheduleID = int.Parse(SQLReader["ScheduleID"].ToString());
                        obj.FullNamespace = SQLReader["FullNamespace"].ToString();
                        obj.NextStart = SQLReader["NextStart"].ToString();
                        obj.EveryMin = int.Parse(SQLReader["EveryMin"].ToString());
                        obj.IsEnable = (Boolean)SQLReader["IsEnable"];
                        obj.StartDate = SQLReader["StartDate"].ToString();
                        obj.EndDate = SQLReader["EndDate"].ToString();
                        obj.RunningMode = (RunningMode)(Convert.ToInt32(SQLReader["RunningMode"].ToString()));
                        lstTasks.Add(obj);
                    }
                }
                catch (Exception e)
                {
                    throw e;
                }
                finally
                {
                    if (SQLReader != null)
                    {
                        SQLReader.Close();
                    }
                }
            }

            return lstTasks;


        }
 public static void RemoveFromScheduleQueue(Schedule scheduleItem)
 {
     try
     {
         using (ScheduleQueue.GetWriteLock(LockTimeout))
         {
             ScheduleHistory item = ScheduleQueue.Where(si => si.ScheduleID == scheduleItem.ScheduleID).SingleOrDefault();
             if (item != null)
             {
                 ScheduleQueue.Remove(item);
             }
         }
     }
     catch (ApplicationException ex)
     {
      
         Interlocked.Increment(ref _writerTimeouts);
         ErrorLogger.SchedulerProcessException(ex);
     }
 }
        internal static bool IsInQueue(Schedule scheduleItem)
        {
            try
            {
                using (ScheduleQueue.GetReadLock(LockTimeout))
                {
                    return ScheduleQueue.Any(si => si.ScheduleID == scheduleItem.ScheduleID);
                }
            }
            catch (ApplicationException)
            {

                Interlocked.Increment(ref _readerTimeouts);
                return false;
            }
        }
        private static bool IsInProgress(Schedule scheduleItem)
        {
            try
            {
                using (ScheduleInProgress.GetReadLock(LockTimeout))
                {
                    return ScheduleInProgress.Any(si => si.ScheduleID == scheduleItem.ScheduleID);
                }
            }
            catch (ApplicationException ex)
            {

                Interlocked.Increment(ref _readerTimeouts);
                ErrorLogger.SchedulerProcessException(ex);
                return false;
            }
        }
 //Add a queue request to Threadpool with a 
 //callback to RunPooledThread which calls Run()
 public void AddQueueUserWorkItem(Schedule s)
 {
     numberOfProcessesInQueue += 1;
     numberOfProcesses += 1;
     var obj = new ScheduleHistory(s);
     try
     {
         //Create a callback to subroutine RunPooledThread
         WaitCallback callback = RunPooledThread;
         //And put in a request to ThreadPool to run the process.
         ThreadPool.QueueUserWorkItem(callback, obj);
         Thread.Sleep(1000);
     }
     catch (Exception exc)
     {
         ErrorLogger.log(s, exc, "AddQueueUserWorkItem");
     }
 }
        public static string GetNextStart(Schedule objScheduleHistory)
        {
            if (objScheduleHistory.RunningMode != RunningMode.Once)
            {
                if (string.IsNullOrEmpty(objScheduleHistory.NextStart))
                {
                    objScheduleHistory.NextStart = Convert.ToString(DateTime.Parse(objScheduleHistory.StartDate).ToShortDateString() + " " + objScheduleHistory.StartHour + ":" + objScheduleHistory.StartMin + ":00");

                }
                else if (!objScheduleHistory.CatchUpEnabled)
                {
                    objScheduleHistory.NextStart = Convert.ToString(DateTime.Now);

                }


            }
            switch (objScheduleHistory.RunningMode)
            {

                case RunningMode.Hourly:

                    objScheduleHistory.NextStart = Convert.ToString(DateTime.Parse(objScheduleHistory.NextStart).AddHours(objScheduleHistory.EveryHours).AddMinutes(objScheduleHistory.EveryMin));
                    break;

                case RunningMode.Daily:
                    objScheduleHistory.NextStart = Convert.ToString(DateTime.Parse(objScheduleHistory.NextStart).AddDays(objScheduleHistory.RepeatDays));
                    break;
                case RunningMode.Weekly:
                    int day = GetNextScheduleWeekDay(objScheduleHistory.ScheduleID, (int)DateTime.Parse(objScheduleHistory.NextStart).DayOfWeek + 1);
                    DateTime now = DateTime.Parse(DateTime.Now.ToShortDateString() + "  " + objScheduleHistory.StartHour + ":" + objScheduleHistory.StartMin + ":00");

                    int nextday = 0;
                    int currentstartday = (int)now.DayOfWeek + 1;

                    if (day > currentstartday) nextday = day - currentstartday;
                    else nextday = 7 - currentstartday + day;

                    objScheduleHistory.NextStart = Convert.ToString(now.AddDays(nextday));
                    break;

                case RunningMode.WeekNumber:

                    day = GetNextScheduleWeekDay(objScheduleHistory.ScheduleID, (int)DateTime.Parse(objScheduleHistory.NextStart).DayOfWeek + 1);
                    now = DateTime.Parse(DateTime.Now.ToShortDateString() + "  " + objScheduleHistory.StartHour + ":" + objScheduleHistory.StartMin + ":00");

                    nextday = 0;
                    currentstartday = (int)now.DayOfWeek + 1;
                    int nextMonth = now.Month;
                    if (day > currentstartday)
                    {
                        nextday = now.Day + day - currentstartday;
                    }
                    else
                    {
                        nextMonth = SchedulerController.ScheduleDateGetNextMonth(objScheduleHistory.ScheduleID, DateTime.Parse(objScheduleHistory.NextStart).Month);

                        nextday = objScheduleHistory.RepeatWeeks * 7 - 7 + day;
                    }

                    DateTime nextDate = new DateTime(now.Year, nextMonth, nextday);

                    objScheduleHistory.NextStart = Convert.ToString(nextDate);
                    break;

                case RunningMode.Calendar:

                    objScheduleHistory.NextStart = Convert.ToString(GetNextScheduleDate(objScheduleHistory.ScheduleID, objScheduleHistory.NextStart));
                    //objScheduleHistory.NextStart = Convert.ToString(DateTime.Parse(objScheduleHistory.NextStart).AddDays(objScheduleHistory.RepeatDays));                       

                    break;

                case RunningMode.Once:
                    objScheduleHistory.NextStart = string.Empty;
                    break;



            }
            if (objScheduleHistory.NextStart != string.Empty && DateTime.Parse(objScheduleHistory.NextStart) > DateTime.Parse(objScheduleHistory.EndDate))
                objScheduleHistory.NextStart = string.Empty;
            return objScheduleHistory.NextStart;
        }
        public static void RunScheduleItemNow(Schedule schedule)
        {

            Scheduler.RemoveFromScheduleQueue(schedule);
            ScheduleHistory scheduleHistory = new ScheduleHistory(schedule);


            if (schedule.IsEnable)
                Scheduler.AddToScheduleQueue(scheduleHistory);

        }
        public static void UpdateSchedule(Schedule objSchedule, List<string> WeekDays, List<string> Months, string Dates)
        {
            DateTime currentDate = DateTime.Now;
            DateTime tmpNextStartDate = new DateTime(currentDate.Year, currentDate.Month, currentDate.Day, objSchedule.StartHour, objSchedule.StartMin, 0);

            try
            {

                Scheduler.RemoveFromScheduleQueue(objSchedule);
                SchedulerDataProvider.ScheduleRepeatOptionDelete(objSchedule.ScheduleID);
                if (WeekDays.Count > 0) AddNewScheduleWeeks(objSchedule.ScheduleID, WeekDays);
                if (Months.Count > 0) AddNewScheduleMonths(objSchedule.ScheduleID, Months);
                if (!string.IsNullOrEmpty(Dates) && Dates.Trim().Length > 0) AddNewScheduleDate(objSchedule.ScheduleID, Dates);

                objSchedule.NextStart = UpdateTaskHistoryNextStartDate(objSchedule.ScheduleID);
                SchedulerDataProvider.UpdateSchedule(objSchedule);

                RunScheduleItemNow(objSchedule);
            }
            catch (Exception)
            {

                throw;
            }
        }