using System;
using System.IO;
using System.Net;
using System.Globalization;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace InvExplorer.Web
{
    /// <summary>
    /// Google stock information provider.
    /// </summary>
    /// <remarks>
    /// * Getting financial data from Google	
    ///   http://www.codeproject.com/KB/silverlight/visualizingstockdata.aspx
    ///   
    ///   Live data:
    ///   http://www.google.com/finance/info?q={stockCode}
    ///   
    ///   Historical data:
    ///   http://finance.google.com/finance/historical?q=MSFT&startdate=1/1/2007&enddate=1/1/2012&output=csv
    ///   
    /// </remarks>
    public class GoogleAssetInfoProvider : IAssetIInfoProvider
    {
        static List<SymbolName> _symbolNames;

        // ** IAssetIInfoProvider
        public List<double> GetCurrentPrice(string symbol)
        {
            var currChange = new List<double>();

            var fmt = "http://www.google.com/finance/info?q={0}";
            var address = string.Format(fmt, symbol);

            var wc = new WebClient();
            try
            {
                var data = wc.DownloadData(address);
                using (var ms = new MemoryStream(data))
                using (var sr = new StreamReader(ms))
                {
                    var line = sr.ReadToEnd();
                    currChange.Add(GetJSonItemDouble(line, "l"));
                    currChange.Add(GetJSonItemDouble(line, "c"));
                }
            }
            catch (Exception x)
            {
                Debug.WriteLine("error retrieving data for " + symbol + ":\r\n\t" + x.Message);
            }

            return currChange;
        }
        public List<AssetPrice> GetAssetPrices(string symbol, DateTime start, DateTime end)
        {
            var list = new List<AssetPrice>();

            var fmt = "http://finance.google.com/finance/historical?q={0}&startdate={1:MM/dd/yy}&enddate={2:MM/dd/yy}&output=csv";
            var address = string.Format(fmt, symbol, start, end);

            var wc = new WebClient();
            try
            {
                var data = wc.DownloadData(address);

                using (var ms = new MemoryStream(data))
                using (var sr = new StreamReader(ms))
                {
                    // skip title: Date,Open,High,Low,Close,Volume
                    sr.ReadLine();

                    // read data
                    var ic = CultureInfo.InvariantCulture;
                    for (var line = sr.ReadLine(); line != null; line = sr.ReadLine())
                    {
                        var parts = line.Split(',');
                        var sp = new AssetPrice();
                        sp.Date = DateTime.Parse(parts[0], ic);
                        sp.Price = double.Parse(parts[4], ic);
                        list.Add(sp);
                    }
                }
            }
            catch (Exception x)
            {
                Debug.WriteLine("error retrieving data for " + symbol + ":\r\n\t" + x.Message);
            }

            return list;
        }
        public List<SymbolName> GetAssetSymbolNames()
        {
            if (_symbolNames == null)
            {
                _symbolNames = SymbolName.LoadSymbolNames();
            }
            return _symbolNames;
        }

        // ** implementation
        double GetJSonItemDouble(string line, string name)
        {
            var pos = line.IndexOf(string.Format("\"{0}\"", name));
            if (pos > -1)
            {
                pos = line.IndexOf(":", pos);
                if (pos > -1)
                {
                    var start = line.IndexOf("\"", pos);
                    var end = line.IndexOf("\"", start + 1);
                    var value = line.Substring(start + 1, end - start - 1);
                    return double.Parse(value);
                }
            }
            return double.NaN;
        }
    }
}