using System.Collections.Generic;
using System;
using System.Drawing;
using System.Diagnostics;
using System.Data;
using System.Collections;
using System.Windows.Forms;
using System.Text;
using System.IO;

namespace vmsnet
{
	public class CFDBK
	{
		string _BaseDir;
		
		System.Text.StringBuilder StrBuf; ////데이터버퍼
		DateTime LastTime; ////데이터시간
		System.IO.FileInfo File; ////데이터파일정보
		
		public CFDBK(params string[] dirarrays)
        {
            var dir = System.IO.Path.Combine(dirarrays);
            _BaseDir = dir;
			if (System.IO.Directory.Exists(_BaseDir) == false)
			{
				System.IO.Directory.CreateDirectory(_BaseDir);
			}
			
			StrBuf = new System.Text.StringBuilder();
			LastTime = DateTime.Now;
			File = null;
		}
		
		////지정한 기간내 파일의 존재여부를 확인합니다.
		public int GetfileCount(DateTime sd, DateTime ed)
		{
			return GetfileS(sd, ed).Count;
		}
		
		/// <summary>
		/// 데이터를 기록합니다.
		/// </summary>
		/// <param name="time">기록시간(파일명이 결정됨)</param>
		/// <param name="buffer">기록된데이터</param>
		/// <param name="Header">데이터의헤더(신규파일생성시)</param>
		/// <returns></returns>
		/// <remarks></remarks>
		public bool InsertData(DateTime time, string buffer, StringBuilder Header)
		{
			string DayStr = time.ToString("yyyyMMdd");
			//Dim TableIndex As Byte = table.Substring(5, 1)
			
			////해당데이터의 시간과 파일정보를 기록
			LastTime = time;
			File = new System.IO.FileInfo(_BaseDir + "\\" + DayStr.Substring(0, 4) + "\\" + DayStr.Substring(4, 2) + "\\" + DayStr.Substring(6) + "\\" + 
																															(time.Hour + 1).ToString("00") +".txt");
			if (!File.Directory.Exists)
			{
				File.Directory.Create();
			}
			
			////파일이 없다면 제목줄을 생성해준다.
			if (!File.Exists)
			{
                //File.WriteText(Header, true);		// 이전은 단독모드
                /* 작성자: 이재웅, 작성일: 2024-09-23, 작성내용: 접근모드를 공유모드로 전환 */
                using (FileStream fs = new FileStream(File.FullName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
                using (StreamWriter writer = new StreamWriter(fs))
                { writer.WriteLine(Header); }				
			}
			
			StrBuf.AppendLine(System.Convert.ToString("\t" + time.ToFileTime().ToString() + buffer));
			
			////4kb 단위로 파일을 기록한다.
			if (StrBuf.Length > 500) ////실제파일 기록은 5초마다 한다.
			{
                //File.WriteText(StrBuf, true);		// 이전은 단독모드
                /* 작성자: 이재웅, 작성일: 2024-09-23, 작성내용: 접근모드를 공유모드로 전환 */
                using (FileStream fs = new FileStream(File.FullName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
                using (StreamWriter writer = new StreamWriter(fs))
                { writer.Write(StrBuf.ToString()); }
				
				StrBuf.Clear();
			}
			
			return true;
		}
		
		~CFDBK()
		{
			if (StrBuf.Length > 0) File.WriteText(StrBuf, true);
			StrBuf.Clear();
			
		}
		
		/// <summary>
		/// 저장폴더내에 존재하는 날짜정보를 반환합니다.
		/// </summary>
		/// <returns></returns>
		/// <remarks></remarks>
		public List<string> GetDateList()
		{
			List<string> REtval = new List<string>();
			
			System.IO.DirectoryInfo BDI = new System.IO.DirectoryInfo(_BaseDir);
			foreach (System.IO.DirectoryInfo Fd_Year in BDI.GetDirectories())
			{
				foreach (System.IO.DirectoryInfo FD_Mon in Fd_Year.GetDirectories())
				{
					foreach (System.IO.DirectoryInfo Fd_Day in FD_Mon.GetDirectories())
					{
						if (Fd_Day.GetFiles().Length > 0)
						{
							REtval.Add(Fd_Year.Name + FD_Mon.Name + Fd_Day.Name);
						}
					}
				}
			}
			
			REtval.Sort();
			return REtval;
		}
		
		
		
		////기간내 존재하는 파일을 반환합니다(테이블단위)
		public List<string> GetfileS(DateTime sd, DateTime ed)
		{
			List<string> REtval = new List<string>();
			int SttYear = sd.Year;
			int EndYear = ed.Year;
			if (EndYear < SttYear)
			{
				return REtval;
			}
			
			int SttMonth = sd.Month;
			int EndMonth = ed.Month;
			
			int SttDay = sd.Day;
			int EndDay = ed.Day;
			
			int si = System.Convert.ToInt32(sd.ToString("yyyyMMdd"));
			int ei = System.Convert.ToInt32(ed.ToString("yyyyMMdd"));
			bool SameDay = si == ei ? true : false;
			
			////20140101
			for (int dayinfo = si; dayinfo <= ei; dayinfo++)
			{
				string DayStr = dayinfo.ToString();
				System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(_BaseDir + "\\" + DayStr.Substring(0, 4) + "\\" + DayStr.Substring(4, 2) + "\\" + DayStr.Substring(6));
				if (!dir.Exists)
				{
					continue;
				}
				////폴더가 존재하므로 해당 테이블파일이 존재하는지 확인한다
				
				if (SameDay)
				{
					////동일날짜라면 해당 시간대만 조회하면됨
					for (int hourinfo = int.Parse(sd.ToString("HH")); hourinfo <= int.Parse(ed.ToString("HH")); hourinfo++)
					{
						string fn = dir.FullName + "\\" + (hourinfo + 1).ToString("00") +".txt";
						if (System.IO.File.Exists(fn))
						{
							REtval.Add(fn);
						}
					}
				}
				else
				{
					if (dayinfo == si) ////시작일이라면 시작시간부터 24시까지 이다.
					{
						for (int hourinfo = int.Parse(sd.ToString("HH")); hourinfo <= 23; hourinfo++)
						{
							string fn = dir.FullName + "\\" + (hourinfo + 1).ToString("00") +".txt";
							if (System.IO.File.Exists(fn))
							{
								REtval.Add(fn);
							}
						}
					}
					else if (dayinfo == ei) ////종료일이라면 1~ 종료시까지이다.
					{
						for (int hourinfo = 0; hourinfo <= int.Parse(ed.ToString("HH")); hourinfo++)
						{
							string fn = dir.FullName + "\\" + (hourinfo + 1).ToString("00") +".txt";
							if (System.IO.File.Exists(fn))
							{
								REtval.Add(fn);
							}
						}
					}
					else
					{
						////중간에 끼어있는 날짜라면 1~24모두가 속한다.
						for (int hourinfo = 0; hourinfo <= 23; hourinfo++)
						{
							string fn = dir.FullName + "\\" + (hourinfo + 1).ToString("00") +".txt";
							if (System.IO.File.Exists(fn))
							{
								REtval.Add(fn);
							}
						}
					}
				}
			}
			REtval.Sort();
			return REtval;
		}
		
	}
	
}
