using System;
using DataClients;
using System.Linq;
using System.Data.Odbc;
using System.Threading;
using System.IO;

namespace Korp90TimePasport
{
	class Program
	{
		static int loopTime = 5000;
		static void Main(string[] args)
		{
			SybaseBD.CreateDbConnection();
			var stpC = new STPClient();
			Console.WriteLine("Start PasportTime Korp90");
			var currDateTime = new DateTime(2001, 02, 21);
			//var currDateTime = new DateTime(2005, 01, 01);

			while (!SybaseBD.CheckConnection()) Thread.Sleep(loopTime);

			var lastDate = SybaseBD.LastDate();
			currDateTime = lastDate.HasValue ? lastDate.Value : currDateTime;


			while (true)
			{
				var cycle_CheckConnection = true;
				while (cycle_CheckConnection)
				{
					cycle_CheckConnection = !(SybaseBD.CheckConnection() && stpC.CheckConnection());
					if (cycle_CheckConnection) Thread.Sleep(loopTime);
				}
				Console.WriteLine("Check date: " + currDateTime.ToString("yyyy.MM.dd"));

				var listPasport = stpC.GetListPasport(currDateTime);
				foreach (var (pasp_name, pasp_dir) in listPasport)
				{
					if (!pasp_name.Contains('-')) continue;
					var convVdp = int.TryParse(pasp_name.Split('-')[1], out int vdp);
					if (convVdp && vdp >= 91 && vdp < 94)
					{
						Console.WriteLine("Find: " + pasp_name.ToString());
						var pasp = stpC.GetPasport(pasp_dir);
						var paspBD = SybaseBD.FindPasport(pasp_name);

						if (!paspBD.exist)
						{
							Console.WriteLine("Pasport " + pasp_name + " not exist in DB.");
							try
							{
								using (StreamWriter file = new StreamWriter(Directory.GetCurrentDirectory() + "/NotExistedPlav.txt", true))
								{
									file.WriteLine(
										pasp_name + "\t" +
										pasp.time_start.ToString("yyyy-MM-dd HH:mm:ss.f") + "\t" +
										pasp.time_end.ToString("yyyy-MM-dd HH:mm:ss.f"));
								}
							}
							catch (Exception e)
							{
								Console.WriteLine("Can't write to file information:" + e.Message);
							}
						}
						else
						{
							if (!paspBD.d_beg.HasValue || paspBD.d_beg.Value != pasp.time_start)
							{
								Console.WriteLine("Update " + pasp_name + " timeStart:");
								Console.WriteLine("\t" + paspBD.d_beg.ToString() + " -> " + pasp.time_start);
								SybaseBD.UpdateTimeStart(pasp_name, pasp.time_start);
							}
							if (!paspBD.d_end.HasValue || paspBD.d_end.Value != pasp.time_end)
							{
								Console.WriteLine("Update " + pasp_name + " timeEnd:");
								Console.WriteLine("\t" + paspBD.d_end.ToString() + " -> " + pasp.time_end);
								SybaseBD.UpdateTimeEnd(pasp_name, pasp.time_end);
							}
						}
						Console.WriteLine("End work with " + pasp_name);
					}
				}

				currDateTime = currDateTime.AddDays(1);
				if (currDateTime > DateTime.Now && currDateTime.Day != DateTime.Now.Day)
				{
					Console.WriteLine("Wait 5 minutes");
					currDateTime = DateTime.Now.AddHours(-2);
					Thread.Sleep(300000);
				}

			}
		}
	}

	static class SybaseBD
	{
		static private OdbcConnection dbConnect;

		static public bool CheckConnection()
		{
			try
			{
				dbConnect.Open();
			}
			catch(Exception e)
			{
				Console.Write("Can't connection to DB: ");
				Console.WriteLine(e.Message);
				return false;
			}
			finally
			{
				dbConnect.Close();
			}
			return true;
		}
		static public void CreateDbConnection()
		{
			dbConnect = new OdbcConnection("Driver={SQL Anywhere 12};UID=asutp;PWD=tvso;DBN=ceh32;HOST=10.10.45.3:2638;");
		}

		static public DBPasport FindPasport(string nPlav)
		{
			var result = new DBPasport();
			try
			{
				dbConnect.Open();

				using (OdbcCommand dbCmd = dbConnect.CreateCommand())
				{
					dbCmd.CommandText = "select top 1 d_beg,d_end from KORP_90.Tab_korp_90 where nplav=\'" + nPlav + "\'";
					using (OdbcDataReader dbReader = dbCmd.ExecuteReader())
					{
						int countColumn = dbReader.FieldCount;
						if (dbReader.Read())
						{
							result.exist = true;
							if (dbReader.GetName(0) == "d_beg" && dbReader.GetName(1) == "d_end")
							{
								if (!dbReader.IsDBNull(0))
									result.d_beg = dbReader.GetDateTime(0);
								if (!dbReader.IsDBNull(1))
									result.d_end = dbReader.GetDateTime(1);
							}
						}
						dbReader.Close();
					}
					dbCmd.Dispose();
				}
			}
			catch (Exception e)
			{
				Console.Write("Error while search pasport in DB: ");
				Console.WriteLine(e.Message);
			}
			finally
			{
				dbConnect.Close();
			}
			return result;
		}
		static public DateTime? LastDate()
		{
			DateTime? result = null;
			try
			{
				dbConnect.Open();
				using (OdbcCommand dbCmd = dbConnect.CreateCommand())
				{
					dbCmd.CommandText = "select top 1 d_beg from KORP_90.Tab_korp_90 order by d_beg desc";
					using (OdbcDataReader dbReader = dbCmd.ExecuteReader())
					{
						if (dbReader.Read())
						{
							if (dbReader.GetName(0) == "d_beg")
							{
								if (!dbReader.IsDBNull(0))
								{
									var lastDate = dbReader.GetDateTime(0);
									result = !result.HasValue ? lastDate : result.Value < lastDate ? lastDate : result;
								}
							}
						}
						dbReader.Close();
					}
					dbCmd.Dispose();
				}
			}
			catch (Exception e)
			{
				Console.WriteLine(e.Message);
			}
			finally
			{
				dbConnect.Close();
			}
			return result;
		}

		static public bool UpdateTimeStart(string nplav, DateTime start)
		{
			var result = 0;
			try
			{
				dbConnect.Open();
				using (OdbcCommand dbCmd = dbConnect.CreateCommand())
				{
					dbCmd.CommandText =
						"update KORP_90.Tab_korp_90 " +
						"set d_beg=\'" + start.ToString("yyyy-MM-dd HH:mm:ss.f") + "\' " +
						"where nplav=\'" + nplav + "\'";
					result = dbCmd.ExecuteNonQuery();
					dbCmd.Dispose();
				}
			}
			catch (Exception e)
			{
				Console.WriteLine(e.Message);
			}
			finally
			{
				dbConnect.Close();
			}
			if (result == 1) return true;
			else return false;
		}

		static public bool UpdateTimeEnd(string nplav, DateTime end)
		{
			var result = 0;
			try
			{
				dbConnect.Open();
				using (OdbcCommand dbCmd = dbConnect.CreateCommand())
				{
					dbCmd.CommandText =
						"update KORP_90.Tab_korp_90 " +
						"set d_end=\'" + end.ToString("yyyy-MM-dd HH:mm:ss.f") + "\' " +
						"where nplav=\'" + nplav + "\'";
					result = dbCmd.ExecuteNonQuery();
					dbCmd.Dispose();
				}
			}
			catch (Exception e)
			{
				Console.WriteLine(e.Message);
			}
			finally
			{
				dbConnect.Close();
			}
			if (result == 1) return true;
			else return false;
		}

	}

	class DBPasport
	{
		public bool exist = false;
		public DateTime? d_beg = null;
		public DateTime? d_end = null;
	}
}
