using Npgsql;
using NpgsqlTypes;
using skyscraper5.Skyscraper;
using skyscraper5.Skyscraper.Equipment;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace skyscraper5.Data.PostgreSql
{
	public partial class PostgresqlDataStore
	{
		private int uiVersion;

		public void UiSetVersion(int version)
		{
			this.uiVersion = version;
		}

		public List<LnbEntity> UiLnbTypesListAll()
		{
			List<LnbEntity> lnbTypes = new List<LnbEntity>();
			using (NpgsqlConnection conn = new NpgsqlConnection(connectionStringBuilder.ToString()))
			{
				conn.Open();
				NpgsqlCommand cmd = conn.CreateCommand();
				cmd.CommandText = "SELECT * FROM skyscraper5_lnbs";
				NpgsqlDataReader dataReader = cmd.ExecuteReader();
				while (dataReader.Read())
				{
					int id = dataReader.GetInt32(0);
					DateTime added = dataReader.GetDateTime(1);
					string name = dataReader.GetString(2);
					int lof1 = dataReader.GetInt32(3);
					int lof2 = dataReader.GetInt32(4);
					int lofSw = dataReader.GetInt32(5);
					int minFreq = dataReader.GetInt32(6);
					int maxFreq = dataReader.GetInt32(7);
					lnbTypes.Add(new LnbEntity("", name, lof1, lof2, lofSw, minFreq, maxFreq) { DateAdded = added, Id = id });
				}

				dataReader.Close();
				cmd.Dispose();
				conn.Close();
			}

			return lnbTypes;
		}

		public void UiLnbTypesAdd(LnbEntity defaultLnbType)
		{
			using (NpgsqlConnection conn = new NpgsqlConnection(connectionStringBuilder.ToString()))
			{
				conn.Open();
				NpgsqlCommand cmd = conn.CreateCommand();
				cmd.CommandText =
					"INSERT INTO skyscraper5_lnbs (name, lof1, lof2, lof_sw, min_freq, max_freq) VALUES (@name,@lof1,@lof2,@lof_sw,@min_freq,@max_freq)";
				cmd.Parameters.AddWithValue("@name", NpgsqlDbType.Text, defaultLnbType.Name);
				cmd.Parameters.AddWithValue("@lof1", NpgsqlDbType.Integer, defaultLnbType.Lof1);
				cmd.Parameters.AddWithValue("@lof2", NpgsqlDbType.Integer, defaultLnbType.Lof2);
				cmd.Parameters.AddWithValue("@lof_sw", NpgsqlDbType.Integer, defaultLnbType.LofSw);
				cmd.Parameters.AddWithValue("@min_freq", NpgsqlDbType.Integer, defaultLnbType.MinimumFrequency);
				cmd.Parameters.AddWithValue("@max_freq", NpgsqlDbType.Integer, defaultLnbType.MaximumFrequency);
				cmd.ExecuteNonQuery();
				cmd.Dispose();
				conn.Close();
			}
		}

		public List<DishEntity> UiDishTypesListAll()
		{
			List<DishEntity> result = new List<DishEntity>();
			using (NpgsqlConnection conn = new NpgsqlConnection(connectionStringBuilder.ToString()))
			{
				conn.Open();
				NpgsqlCommand cmd = conn.CreateCommand();
				cmd.CommandText = "SELECT * FROM skyscraper5_dishes";
				NpgsqlDataReader dataReader = cmd.ExecuteReader();
				while (dataReader.Read())
				{
					int id = dataReader.GetInt32(0);
					DateTime added = dataReader.GetDateTime(1);
					string name = dataReader.GetString(2);
					int diameter = dataReader.GetInt32(3);
					DishShape shape = (DishShape)dataReader.GetInt32(4);
					result.Add(new DishEntity("", name, diameter, shape) { DateAdded = added, Id = id });
				}
			}

			return result;
		}

		public void UiDishTypesAdd(DishEntity defaultDishType)
		{
			using (NpgsqlConnection conn = new NpgsqlConnection(connectionStringBuilder.ToString()))
			{
				conn.Open();
				NpgsqlCommand cmd = conn.CreateCommand();
				cmd.CommandText = "INSERT INTO skyscraper5_dishes (name, diameter, shape) VALUES (@name,@diameter,@shape)";
				cmd.Parameters.AddWithValue("@name", NpgsqlDbType.Text, defaultDishType.Name);
				cmd.Parameters.AddWithValue("@diameter", NpgsqlDbType.Integer, defaultDishType.Diameter);
				cmd.Parameters.AddWithValue("@shape", NpgsqlDbType.Integer, (int)defaultDishType.Shape);
				cmd.ExecuteNonQuery();
				cmd.Dispose();
				conn.Close();
			}
		}


		public List<SatellitePositionEntity> UiSatellitesListAll()
		{
			List<SatellitePositionEntity> positions = new List<SatellitePositionEntity>();
			using (NpgsqlConnection conn = new NpgsqlConnection(connectionStringBuilder.ToString()))
			{
				conn.Open();
				NpgsqlCommand cmd = conn.CreateCommand();
				cmd.CommandText = "SELECT * FROM skyscraper5_satellite_positions";
				NpgsqlDataReader reader = cmd.ExecuteReader();
				while (reader.Read())
				{
					float angle = (float)reader.GetDouble(0);
					int cardinal = reader.GetInt32(1);
					string name = reader.GetString(2);
					SatellitePositionEntity child = new SatellitePositionEntity(angle, name);
					positions.Add(child);
				}

				reader.Close();
				cmd.Dispose();
				conn.Close();
			}

			return positions;
		}

		public void UiSatellitesAdd(SatellitePositionEntity newPosition)
		{
			using (NpgsqlConnection conn = new NpgsqlConnection(connectionStringBuilder.ToString()))
			{
				conn.Open();
				NpgsqlCommand cmd = conn.CreateCommand();
				cmd.CommandText =
					"insert into skyscraper5_satellite_positions (angle, cardinal, name, keyversion, key) " +
					"values (@angle, @cardinal, @name, @keyversion, @key)";
				cmd.Parameters.AddWithValue("@angle", NpgsqlDbType.Real, newPosition.angle);
				cmd.Parameters.AddWithValue("@cardinal", NpgsqlDbType.Integer, newPosition.GetCardinalDirectionAsInt());
				cmd.Parameters.AddWithValue("@name", NpgsqlDbType.Text, newPosition.name);
				cmd.Parameters.AddWithValue("@keyversion", NpgsqlDbType.Integer, uiVersion);
				cmd.Parameters.AddWithValue("@key", NpgsqlDbType.Text, newPosition.Checksum.ToString());
				cmd.ExecuteNonQuery();
				cmd.Dispose();
				conn.Close();
			}
		}

		public void UiSatellitesDelete(SatellitePositionEntity satellitePosition)
		{
			using (NpgsqlConnection conn = new NpgsqlConnection(connectionStringBuilder.ToString()))
			{
				conn.Open();
				NpgsqlCommand cmd = conn.CreateCommand();
				cmd.CommandText =
					"DELETE FROM skyscraper5_satellite_positions WHERE keyversion = @keyversion AND key = @key";
				cmd.Parameters.AddWithValue("@keyversion", NpgsqlDbType.Integer, uiVersion);
				cmd.Parameters.AddWithValue("@key", NpgsqlDbType.Text, satellitePosition.Checksum.ToString());
				cmd.ExecuteNonQuery();
				cmd.Dispose();
				conn.Close();
			}
		}

		public bool UiTunerTestFor(TunerMetadata tuner)
		{
			bool result;
			using (NpgsqlConnection conn = new NpgsqlConnection(connectionStringBuilder.ToString()))
			{
				conn.Open();
				NpgsqlCommand cmd = conn.CreateCommand();
				cmd.CommandText =
					"SELECT dateadded FROM skyscraper5_tuners WHERE mac = @mac AND satkeyversion = @satkeyversion";
				cmd.Parameters.AddWithValue("@mac", NpgsqlDbType.Varchar, tuner.MacAddress.ToString());
				cmd.Parameters.AddWithValue("@satkeyversion", NpgsqlDbType.Integer, uiVersion);
				NpgsqlDataReader reader = cmd.ExecuteReader();
				result = reader.Read();
				reader.Close();
				cmd.Dispose();
				conn.Close();
			}

			return result;
		}

		public void UiTunerUpdate(TunerMetadata tuner)
		{
			using (NpgsqlConnection conn = new NpgsqlConnection(connectionStringBuilder.ToString()))
			{
				conn.Open();
				NpgsqlCommand cmd = conn.CreateCommand();
				cmd.CommandText = "UPDATE skyscraper5_tuners " +
								  "SET diseqc_type = @diseqc_type, sat1 = @sat1, sat2 = @sat2, sat3 = @sat3, sat4 = @sat4," +
								  "								   lnb1 = @lnb1, lnb2 = @lnb2, lnb3 = @lnb3, lnb4 = @lnb4," +
								  "                               dish1 =@dish1,dish2 =@dish2,dish3 =@dish3,dish4 =@dish4 " +
								  "WHERE mac = @mac AND satkeyversion = @satkeyversion";
				cmd.Parameters.AddWithValue("@diseqc_type", NpgsqlDbType.Integer, (int)tuner.DiseqcType);
				cmd.Parameters.AddWithValue("@sat1", NpgsqlDbType.Integer, tuner.Satellites[0]);
				cmd.Parameters.AddWithValue("@sat2", NpgsqlDbType.Integer, tuner.Satellites[1]);
				cmd.Parameters.AddWithValue("@sat3", NpgsqlDbType.Integer, tuner.Satellites[2]);
				cmd.Parameters.AddWithValue("@sat4", NpgsqlDbType.Integer, tuner.Satellites[3]);
				cmd.Parameters.AddWithValue("@mac", NpgsqlDbType.Varchar, tuner.MacAddress.ToString());
				cmd.Parameters.AddWithValue("@satkeyversion", NpgsqlDbType.Integer, uiVersion);
				cmd.Parameters.AddWithValue("@lnb1", NpgsqlDbType.Integer, tuner.Lnbs[0]);
				cmd.Parameters.AddWithValue("@lnb2", NpgsqlDbType.Integer, tuner.Lnbs[1]);
				cmd.Parameters.AddWithValue("@lnb3", NpgsqlDbType.Integer, tuner.Lnbs[2]);
				cmd.Parameters.AddWithValue("@lnb4", NpgsqlDbType.Integer, tuner.Lnbs[3]);
				cmd.Parameters.AddWithValue("@dish1", NpgsqlDbType.Integer, tuner.Dishes[0]);
				cmd.Parameters.AddWithValue("@dish2", NpgsqlDbType.Integer, tuner.Dishes[1]);
				cmd.Parameters.AddWithValue("@dish3", NpgsqlDbType.Integer, tuner.Dishes[2]);
				cmd.Parameters.AddWithValue("@dish4", NpgsqlDbType.Integer, tuner.Dishes[3]);
				cmd.ExecuteNonQuery();
				cmd.Dispose();
				conn.Close();
			}
		}

		public void UiTunerInsert(TunerMetadata tuner)
		{
			using (NpgsqlConnection conn = new NpgsqlConnection(connectionStringBuilder.ToString()))
			{
				conn.Open();
				NpgsqlCommand cmd = conn.CreateCommand();
				cmd.CommandText =
					"insert into skyscraper5_tuners (mac, vindex, vname, v_std_type, caps, diseqc_type, sat1, sat2, sat3, sat4, satkeyversion, lnb1, lnb2, lnb3, lnb4, dish1, dish2, dish3, dish4) " +
					"values " +
					"(@mac, @vindex, @vname, @v_std_type, @caps, @diseqc_type, @sat1, @sat2, @sat3, @sat4, @satkeyversion, @lnb1, @lnb2, @lnb3, @lnb4, @dish1, @dish2, @dish3, @dish4)";
				cmd.Parameters.AddWithValue("@mac", NpgsqlDbType.Varchar, tuner.MacAddress.ToString());
				cmd.Parameters.AddWithValue("@vindex", NpgsqlDbType.Integer, tuner.Index);
				cmd.Parameters.AddWithValue("@vname", NpgsqlDbType.Text, tuner.Name);
				cmd.Parameters.AddWithValue("@v_std_type", NpgsqlDbType.Integer, (int)tuner.Type);
				cmd.Parameters.AddWithValue("@caps", NpgsqlDbType.Integer, (int)tuner.Caps);
				cmd.Parameters.AddWithValue("@diseqc_type", NpgsqlDbType.Integer, (int)tuner.DiseqcType);
				cmd.Parameters.AddWithValue("@sat1", NpgsqlDbType.Integer, tuner.Satellites[0]);
				cmd.Parameters.AddWithValue("@sat2", NpgsqlDbType.Integer, tuner.Satellites[1]);
				cmd.Parameters.AddWithValue("@sat3", NpgsqlDbType.Integer, tuner.Satellites[2]);
				cmd.Parameters.AddWithValue("@sat4", NpgsqlDbType.Integer, tuner.Satellites[3]);
				cmd.Parameters.AddWithValue("@satkeyversion", NpgsqlDbType.Integer, uiVersion);
				cmd.Parameters.AddWithValue("@lnb1", NpgsqlDbType.Integer, tuner.Lnbs[0]);
				cmd.Parameters.AddWithValue("@lnb2", NpgsqlDbType.Integer, tuner.Lnbs[1]);
				cmd.Parameters.AddWithValue("@lnb3", NpgsqlDbType.Integer, tuner.Lnbs[2]);
				cmd.Parameters.AddWithValue("@lnb4", NpgsqlDbType.Integer, tuner.Lnbs[3]);
				cmd.Parameters.AddWithValue("@dish1", NpgsqlDbType.Integer, tuner.Dishes[0]);
				cmd.Parameters.AddWithValue("@dish2", NpgsqlDbType.Integer, tuner.Dishes[1]);
				cmd.Parameters.AddWithValue("@dish3", NpgsqlDbType.Integer, tuner.Dishes[2]);
				cmd.Parameters.AddWithValue("@dish4", NpgsqlDbType.Integer, tuner.Dishes[3]);
				cmd.ExecuteNonQuery();
				cmd.Dispose();
				conn.Close();
			}
		}

		public void UiTunerGetConfiguration(TunerMetadata foundTuner)
		{
			using (NpgsqlConnection conn = new NpgsqlConnection(connectionStringBuilder.ToString()))
			{
				conn.Open();
				NpgsqlCommand cmd = conn.CreateCommand();
				cmd.CommandText =
					"SELECT diseqc_type, sat1, sat2, sat3, sat4, lnb1, lnb2, lnb3, lnb4, dish1, dish2, dish3, dish4 FROM skyscraper5_tuners WHERE mac = @mac AND satkeyversion = @satkeyversion";
				cmd.Parameters.AddWithValue("@mac", NpgsqlDbType.Varchar, foundTuner.MacAddress.ToString());
				cmd.Parameters.AddWithValue("@satkeyversion", NpgsqlDbType.Integer, uiVersion);
				NpgsqlDataReader reader = cmd.ExecuteReader();
				if (reader.Read())
				{
					foundTuner.DiseqcType = reader.GetInt32(0);
					foundTuner.Satellites[0] = reader.GetInt32(1);
					foundTuner.Satellites[1] = reader.GetInt32(2);
					foundTuner.Satellites[2] = reader.GetInt32(3);
					foundTuner.Satellites[3] = reader.GetInt32(4);
					foundTuner.Lnbs[0] = reader.GetInt32(5);
					foundTuner.Lnbs[1] = reader.GetInt32(6);
					foundTuner.Lnbs[2] = reader.GetInt32(7);
					foundTuner.Lnbs[3] = reader.GetInt32(8);
					foundTuner.Dishes[0] = reader.GetInt32(9);
					foundTuner.Dishes[1] = reader.GetInt32(10);
					foundTuner.Dishes[2] = reader.GetInt32(11);
					foundTuner.Dishes[3] = reader.GetInt32(12);
				}

				reader.Close();
				cmd.Dispose();
				conn.Close();
			}
		}

	}
}
