using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Data.Edm.Csdl;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using Newtonsoft.Json;
using SharedStorage;
using StackExchange.Redis;

namespace ReverseIndexing
{
    class Program
    {
        static List<PersonRedis> listOfModels = new List<PersonRedis>();
        static List<Task> listOfTasks = new List<Task>();
        
        static int counter = 0;


        static void Main(string[] args)
        {
         
            ConnectionMultiplexer connectionMultiplexer = ConnectionMultiplexer.Connect(SharedStorage.StorageConst.RedisConnectionString);
            IDatabase database = connectionMultiplexer.GetDatabase();

            GetFromDb();
            //GetFromFile();

            var listGroupedByChar = listOfModels.GroupBy(property => property.Key[0]);
            GenerateSet(database);
            UploadToRedis(listGroupedByChar, database);

            WaitForTasks();

            var members = database.SetMembers(StorageConst.RedisSet).OrderBy(prop => prop.ToString()[0]).First();
            var hash = database.HashGetAll(members.ToString());
            foreach (var people in hash)
            {
                Console.WriteLine(people.Value);
            }

            Console.ReadKey();

        }

        private static void GenerateSet(IDatabase database)
        {
            for (var i = 'A'; i < 'Z'; i++)
                database.SetAdd(StorageConst.RedisSet, i.ToString());
        }

        private static void WaitForTasks()
        {
            while (!Task.WhenAll(listOfTasks).IsCompleted)
            {
                Console.WriteLine("Czekam na koniec zadań");
            }
        }

        private static void UploadToRedis(IEnumerable<IGrouping<char, PersonRedis>> list,IDatabase database)
        {
            foreach (var model in list)
            {
                foreach (var values in model)
                {
                    listOfTasks.Add(database.HashSetAsync(model.Key.ToString(),values.Key,values.Value).ContinueWith((result)=>Console.WriteLine(values.Value)));
                }
            }
        }

        private static void GetFromFile()
        {   
            using (var sw = new StreamReader("Database.json"))
            {
                listOfModels = JsonConvert.DeserializeObject<List<PersonRedis>>(sw.ReadToEnd());
            }
        }

        private static void GetFromDb()
        {
            using (
                var connection =
                    new SqlConnection("Server=LukaszSzulc;Database=AdventureWorksDW2008R2_TP;Integrated Security = SSPI")
                )
            {
                connection.Open();
                var command =
                    new SqlCommand(
                        "SELECT EmailAddress,CONCAT(FirstName,' ',LastName) as [KEY] FROM DimCustomer JOIN FactInternetSales ON DimCustomer.CustomerKey = FactInternetSales.CustomerKey ORDER BY [Key]",
                        connection);
                var reader = command.ExecuteReader();
                while (reader.Read())
                {
                    var nosqlModel = new PersonRedis
                    {
                        Key = reader[1].ToString(),
                        Value = (string) reader[0]
                    };
                    AddToList(nosqlModel);
                }
            }
        }

        private static void AddToList(PersonRedis nosqlModel)
        {
            if (listOfModels.Find(property => property.Key == nosqlModel.Key) == null)
            {
                listOfModels.Add(nosqlModel);
            }

        }

    }
}
