using System;
using System.Data;
using System.Diagnostics;
using System.Data.SqlClient;
using System.Collections;
using System.Threading;
using edu.jhu.Cas.Jobs;
using edu.jhu.Cas.Servers;
using edu.jhu.Cas.Util;
using edu.jhu.Cas.Users;

namespace edu.jhu.Cas.Service {
    public class CancelJobsThread : CJobsDBThread {
        public override string ServiceName {
            get {
                return "Cancel Jobs Service";
            }
        }
        public override string ServiceDescription {
            get {
                return "Picks up jobs in the cancelling state and tries to cancel them.";
            }
        }
        public override int DefaultPanicMinutes {get {return 5;}}
        private const string CANCEL_JOBS_QUERY= @"
select jobid from jobs where status = 2
"; 
        static CasJobs cj = new CasJobs();
        static CasJobsAdmin cja = new CasJobsAdmin();
        static CasUsers cu = new CasUsers();
        const int CYCLE_DELAY_SECONDS = 15;
        SqlCommand cjqCom = new SqlCommand();

        public CancelJobsThread()
            : base() {
            base.con.Open();
            cjqCom.Connection = base.con;
            cjqCom.CommandText = CANCEL_JOBS_QUERY;
            cjqCom.Prepare();
        }
        protected override void Run() {
            for (; ; ) {
                try {
                    Thread.Sleep(CYCLE_DELAY_SECONDS * 1000);
                    if (State == CJobsDBState.RUNNING) {
                        DataSet jobids_to_cancel = base.BatchAdminQuery(cjqCom);
                        long jobid;
                        foreach (DataRow dr in jobids_to_cancel.Tables[0].Rows) {
                            jobid = (long)dr[0];
                            Job[] job = cj.FindJob(ID.SERVICE_ID, "jobid = " + jobid);
                            if (job == null) continue;
                            if (job.Length == 0) continue;
                            try {
                                Console.WriteLine("completing cancel for " + job[0].JobID);
                                cja.CompleteCancel(job[0].WebServicesID, jobid, "Transferred cancel request.", null);
                            } catch (Exception e) {
                                CJobsService.Log(e.ToString(), System.Diagnostics.EventLogEntryType.Error);
                            }
                            (new CancellingJobThread(jobid)).StartThread();
                        }
                    }
                    CycleComplete();
                }
                catch (Exception e) {
                    CJobsService.Log(e.ToString(), EventLogEntryType.Error);
                }
            }
        }
        protected override void Halt() {}
        class CancellingJobThread {
            public long jobid;
            public CancellingJobThread(long jobid) {
                this.jobid = jobid;
            }
            public void StartThread() {
                (new Thread(new ThreadStart(this.CancelJob))).Start();
            }
            void CancelJob() {
                try {
                    RunJobsThread.KillRunningJob(jobid);
                }catch(Exception e){
                    CJobsService.Log(e.ToString(),EventLogEntryType.Error);
                }
            }
        }
    }
}