using System;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Collections;
using System.Diagnostics;
using System.Threading;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using edu.jhu.Cas.Jobs;
using edu.jhu.Cas.Plot;
using edu.jhu.Cas.Servers;
using edu.jhu.Cas.Users;
using edu.jhu.Cas.Util;
using net.ivoa.VOTable;
using nom.tam.fits;
using System.Security.Cryptography;
//using SoftwareFX.ChartFX.Lite;
namespace edu.jhu.Cas.Service {
    public class OutputCleanupThread : CJobsDBThread{
        public const int DELAY = 5;//hour
        public DateTime NextOutputCleanUp = DateTime.Now;
        private const double CleanUpPeriod = 1;//in hours
        private const double OutputCleanPeriod = 24;//in hours
        private const int JobLifeTime = 7;//a week      

        public override string ServiceName {
            get {
                return "Output Cleanup Service";
            }
        }
        public override string ServiceDescription {
            get {
                return "Deletes old output files.";
            }
        }
        public override int DefaultPanicMinutes {
            get {
                return DELAY * 60 * 2;//twice the default period in minutes
            }
        }
        public void MaybeSweep() {
            if (DateTime.Now >= NextOutputCleanUp) {
                CJobsService.Log("Deleting old output files ", EventLogEntryType.Information);
                DataSet ds = SqlFactory.select("select path from output where visible > 0");
                foreach (DataRow row in ds.Tables[0].Rows) {
                    try {
                        DirectoryInfo di = new DirectoryInfo(row[0].ToString());
                        
                        FileInfo[] files = di.GetFiles();
                        foreach (FileInfo fi in files) {
                            //if(fi.Exists && fi.GetAccessControl().
                            if (fi.CreationTime < DateTime.Now.AddDays(-JobLifeTime)) {
                                CJobsService.Log("Trying to delete " + fi.FullName, EventLogEntryType.Information);
                                fi.Delete();
                            }
                        }
                    }
                    catch (IOException ie) {
                        if (ie.Message.IndexOf("cannot access") > -1) continue;//skip files we can't read
                    }
                    catch (Exception e) {
                        CJobsService.Log(e.ToString(), EventLogEntryType.Error);
                        continue;
                    }
                }
                string updateJobs = "update jobs set visibility = " + VISIBILITY.NOT_USER_VISIBLE + " where outputtype not like '%query%' " +
                    " and TimeSubmit < (getdate() - " + JobLifeTime + ")";
                SqlFactory.insert(updateJobs);
                NextOutputCleanUp = DateTime.Now.AddHours(OutputCleanPeriod);
            }
        }
        public void OnStop() {
        }
        protected override void Run() {
            for (; ; ) {
                try {
                    if (State == CJobsDBState.RUNNING) {
                        MaybeSweep();
                    }
                    CycleComplete();
                } catch (Exception e) { CJobsService.Log(e.ToString(), EventLogEntryType.Error); }
                Thread.Sleep(DELAY * 60 * 60);
            }
        }
        protected override void Halt() {}
    }
}

