// Metadata Labs Firehose C# example
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;

namespace FirehoseApiTest
{
    class Program
    {
        // This is the standard Firehose request.
        const string FirehoseRequestString = "http://api.metadatalabs.com/firehose.json";

        // Request frequency, in milliseconds
        const int RequestFrequency = 30000;

        static DateTime LastModifiedDate = DateTime.MinValue;
        static Timer TestTimer;

        static void Main(string[] args)
        {
            Console.WriteLine("Initializing ...");
            FirehoseUpdate(null);
            Console.WriteLine("Press Enter to end program.");
            Console.ReadLine();
        }

        static void StartTimer()
        {
            // do a one-shot.
            Console.WriteLine("Next update in {0:N0} seconds.", RequestFrequency/1000);
            TestTimer = new Timer(FirehoseUpdate, null, RequestFrequency, Timeout.Infinite);
        }

        const int BUFF_SIZE = 2048;
        static void FirehoseUpdate(object state)
        {
            var request = (HttpWebRequest)WebRequest.Create(FirehoseRequestString);

            // Request compressed, to conserve bandwidth
            request.AutomaticDecompression = 
                DecompressionMethods.GZip | DecompressionMethods.Deflate;

            if (LastModifiedDate != DateTime.MinValue)
            {
                // Sets If-Modified-Since request header
                request.IfModifiedSince = LastModifiedDate;
            }

            try
            {
                using (var response = (HttpWebResponse)request.GetResponse())
                {
                    Console.WriteLine("{0} - Response received", DateTime.Now);
                    Console.WriteLine("status={0}  contentType={1}  contentLength={2}",
                        response.StatusCode, response.ContentType, response.ContentLength);
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        try
                        {
                            LastModifiedDate = response.LastModified;
                            Console.WriteLine("lastModified={0}", LastModifiedDate);
                        }
                        catch
                        {
                            Console.WriteLine("ERROR getting last modified date.");
                        }

                        // read the response
                        StringBuilder sb = new StringBuilder();
                        using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                        {
                            char[] read = new char[BUFF_SIZE];
                            int count = reader.Read(read, 0, BUFF_SIZE);
                            while (count > 0)
                            {
                                // Dumps the characters on a string and displays the string.
                                String str = new String(read, 0, count);
                                sb.Append(str);
                                count = reader.Read(read, 0, BUFF_SIZE);
                            }
                        }
                        string txtResponse = sb.ToString();
                        // txtResponse now contains the full text of the response.
                        // Here you can call whatever method you want to process the data.
                    }
                }
            }
            catch (WebException wex)
            {
                // HttpWebRequest throws WebException if the request isn't successful.
                // If the server returns [304 - Not Modified], wex.Status will be equal to
                // WebExceptionStatus.ProtocolError, and wex.Response will be equal
                // to HttpWebResponse.NotModified.
                Console.WriteLine("{0} - Exception", DateTime.Now);
                if (wex.Status == WebExceptionStatus.ProtocolError)
                {
                    Console.WriteLine("status={0}", ((HttpWebResponse)wex.Response).StatusCode);
                }
                else
                {
                    Console.WriteLine("status={0}", wex.Status);
                }
            }

            // And set up for the next time.
            StartTimer();
        }
    }
}