using System;
using System.Collections.Generic;


using System.IO;
using Azure.Storage;
using Azure.Storage.Blobs;
using System.Collections;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure.Storage.Auth;
using System.Threading.Tasks;
using System.Text;
using Microsoft.WindowsAzure.Storage.Table;

namespace IntermediatorBotSample
{
    public class Singleton
    {
        public static Singleton instance = null;
        public IList<string> strList = new List<string>();
        public Hashtable myTable = new Hashtable();
        public string newconvid;
        public int i = 0;
        public string x = "";
        //private IList<string> finalList;
        public string finalconvid = "";
        public string finalid = "";
        public List<string> msglist = new List<string>();
        public Hashtable ht;

        


        //Private constructor to deny instance creation of this class from outside
        public Singleton() { }

        //GetInstace method to be used to create or reach the single resource (instance)
        public static Singleton GetInstance()
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }


        public void addId(string Id)
        {
            finalid = Id;
        }

        public void all_messages(List<string> messages)
        {
            msglist = messages;
            
        }
        public List<string> final_msg()
        {
            return (List<string>)msglist;
        }
        //Implement functionality as public instance methods
        public void addconversationid(string conid)
        {
            finalconvid = conid;
            ht = new Hashtable();
            ht.Add(finalconvid, new List<string>());
            Console.WriteLine("1-------------------------------- " + conid);
        }
        public class logEntity : TableEntity
        {
            public logEntity() { }
            public logEntity(string convId, string message)
            {
                PartitionKey = convId;
                RowKey = message;
            }
            public string ConvId => PartitionKey;
            public string Message => RowKey;
            public override string ToString() => $"{ConvId} {Message}";
        }

        public void addToLog(string conid, string message)
        {
            string accName = "azradlppb";
            string accKey = "VLhJjo77rwYnHWaeNh2UlEdswUypR0uWSTyLn6Hu9SWlAYtujHymXZxdFo9kuEK5WcpDwBySpOjizcqxd3hMHA==";

            var storageAccount = new CloudStorageAccount(new StorageCredentials(accName, accKey), true);
            var tableClient = storageAccount.CreateCloudTableClient();
            var logsTable = tableClient.GetTableReference("logs");
            logsTable.CreateIfNotExistsAsync();
            logsTable.ExecuteAsync(TableOperation.InsertOrReplace(new logEntity("100", message)));

        }
        /*public getLogs(string conid, string partitionKey)
        {
            string accName = "azradlppb";
            string accKey = "VLhJjo77rwYnHWaeNh2UlEdswUypR0uWSTyLn6Hu9SWlAYtujHymXZxdFo9kuEK5WcpDwBySpOjizcqxd3hMHA==";
            var storageAccount = new CloudStorageAccount(new StorageCredentials(accName, accKey), false);
            var tableClient = storageAccount.CreateCloudTableClient();
            var logsTable = tableClient.GetTableReference("logs");
            TableOperation retrieve = TableOperation.Retrieve<logEntity>(partitionKey, null);

            TableResult result = logsTable.ExecuteAsync(retrieve);

            Console.WriteLine(((logEntity)result.Result).Date);
            var logs = logsTable.Execute(TableOperation.Retrieve<logEntity>(conid));
        }*/
        public void push(string conid, string id, string message)
        {
            if (message == "end")
            {


                string accName = "azradlppb";
                string accKey = "VLhJjo77rwYnHWaeNh2UlEdswUypR0uWSTyLn6Hu9SWlAYtujHymXZxdFo9kuEK5WcpDwBySpOjizcqxd3hMHA==";

                var storageAccount = new CloudStorageAccount(new StorageCredentials(accName, accKey),true);
                var tableClient = storageAccount.CreateCloudTableClient();
                var logsTable = tableClient.GetTableReference("logs");
                logsTable.CreateIfNotExistsAsync();

                
                // Implement the accout, set true for https for SSL.  
                StorageCredentials creds = new StorageCredentials(accName, accKey);
                CloudStorageAccount strAcc = new CloudStorageAccount(creds, true);

                // Create the blob client.  
                CloudBlobClient blobClient = strAcc.CreateCloudBlobClient();

                // Retrieve a reference to a container.   
                CloudBlobContainer container = blobClient.GetContainerReference("agent");

                // Create the container if it doesn't already exist.  
                container.CreateIfNotExistsAsync();
                string folder = DateTime.Now.ToString("MM-dd-yyyy/");
                string fileName = conid + ".txt";
                DateTime dateLogEntry = DateTime.Now;
                // This creates a reference to the append blob.  
                CloudAppendBlob appBlob = container.GetAppendBlobReference(folder + fileName);

                // Now we are going to check if todays file exists and if it doesn't we create it.  
                /*if (!appBlob.Exists())
                {
                    appBlob.CreateOrReplace();
                }*/
                appBlob.CreateOrReplaceAsync();
                List<string> messages1 = ((List<string>)ht[conid]);
                /*logsTable.ExecuteAsync(TableOperation.InsertOrReplace(new logEntity("1", "++")));
                logsTable.ExecuteAsync(TableOperation.InsertOrReplace(new logEntity("1", "--")));*/
                /*var tasks = new Task[messages1.Count];
                all_messages(messages1);
                for (int k = 0; k < messages1.Count; k++)
                {
                    var bytes = Encoding.UTF8.GetBytes(messages1[k]);

                    var stream = new MemoryStream(bytes);

                    tasks[i] = appBlob.AppendBlockAsync(stream);

                }*/
                var tasks = new Task[messages1.Count];
                all_messages(messages1);
                for (int i = 0; i < messages1.Count; i++)
                    logsTable.ExecuteAsync(TableOperation.InsertOrReplace(new logEntity(conid.ToString(), messages1[i].ToString())));
                //Task.WaitAll(tasks);
                /*for (int i = 0; i < 100; i++)
                {
                    var message = string.Format("Appending log number {0} to an append blob.\r\n", i);

                    var bytes = Encoding.UTF8.GetBytes(message);

                    var stream = new MemoryStream(bytes);

                    tasks[i] = blob.AppendBlockAsync(stream);
                }
*/

                /*List<string> messages1 = ((List<string>)ht[conid]);
                all_messages(messages1);
                for (int k = 0; k < messages1.Count; k++)
                {
                    appBlob.AppendTextAsync(messages1[k].ToString());
                    appBlob.AppendTextAsync("\n");

                    *//*sw.Flush();
                    stream.Position = 0;
                    blob.UploadFromStream(stream);*//*

                }*/
                // Add the entry to file.  




                /*string connection = "DefaultEndpointsProtocol=https;AccountName=azradlppb;AccountKey=VLhJjo77rwYnHWaeNh2UlEdswUypR0uWSTyLn6Hu9SWlAYtujHymXZxdFo9kuEK5WcpDwBySpOjizcqxd3hMHA==;EndpointSuffix=core.windows.net";
                string folder = DateTime.Now.ToString("MM-dd-yyyy/");
                string fileName = conid + ".txt";
                Console.WriteLine(fileName);
                string containerString = "agent";
                CloudStorageAccount storage = CloudStorageAccount.Parse(connection);
                CloudBlobClient client = storage.CreateCloudBlobClient();
                CloudBlobContainer container = client.GetContainerReference(containerString);
                CloudAppendBlob blob = container.GetAppendBlobReference(folder + fileName);
                //if (!blob.ExistsAsync())
                blob.CreateOrReplaceAsync();
                blob.AppendTextAsync("hiiiiiiiiiiiiii");
                    blob.AppendTextAsync("Vamshi");
                List<string> messages1 = ((List<string>)ht[conid]);
                for (int k = 0; k < messages1.Count; k++)
                {
                    blob.AppendTextAsync(messages1[k].ToString());
                    blob.AppendTextAsync("\n");

                    *//*sw.Flush();
                    stream.Position = 0;
                    blob.UploadFromStream(stream);*//*

                }
                using (MemoryStream stream = new MemoryStream())
                using (StreamWriter sw = new StreamWriter(stream))
                {
                    //blob.DownloadToStreamAsync(stream);
                    Console.WriteLine("2--------------------------------" + (List<string>)ht[conid]);
                    *//*foreach (string s in ((List<string>)ht[conid]))
                    {

                        //blob.DownloadToStream(stream);
                        sw.Write(s);
                        sw.Write("\n");
                        sw.Flush();
                        stream.Position = 0;
                        blob.UploadFromStreamAsync(stream);
                    }*//*
                    //ht.Remove(conid);
                    List<string> messages = ((List<string>)ht[conid]);

                    Console.WriteLine("2--------------------------------" + messages);

                    //foreach (string s in ((List<string>)ht[conid]))
                    all_messages(messages);
                    for (int i = 0; i < messages.Count; i++)
                    {
                        blob.AppendTextAsync(messages[i].ToString());
                        blob.AppendTextAsync("\n");
                        sw.WriteLineAsync(messages[i].ToString());
                        sw.WriteAsync("\n");
                        *//*sw.Flush();
                        stream.Position = 0;
                        blob.UploadFromStream(stream);*//*

                    }
                    sw.WriteAsync("======================================================================================");
                    sw.WriteAsync("\n");
                    sw.Flush();
                    stream.Position = 0;
                    blob.AppendFromStreamAsync(stream);
                    stream.Close();
                    //blob.UploadFromStream(stream);*/

                //ht.Remove(conid);

                //ht.Clear();

                //}
                ht.Remove(conid);
            }
        }

        public void Log(string message)
        {
            try
            {
                string msg = message;
                ((List<string>)ht[finalconvid]).Add(msg);

                push(finalconvid, finalconvid, message);
                //push(finalid, message);
            }
            catch
            {
                Console.WriteLine("--");
            }


        }
    }
}
