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

namespace InvExplorer.Web
{
    /// <summary>
    /// Yahoo stock information provider.
    /// </summary>
    /// <remarks>
    /// 
    ///   Live data:
    ///   http://www.gummy-stuff.org/Yahoo-data.htm
    /// 
    ///   Historical data:
    ///   http://ichart.finance.yahoo.com/table.csv?s=AAPL&a=3&b=12&c=2005&d=2&e=20&f=2012&g=d&ignore=.csv
    ///   Date	Open	High	Low	Close	Volume	Adj Close
    ///   3/19/2012	598.37	601.77	589.05	601.1	32110600	601.1
    ///   3/16/2012	584.72	589.2	578	585.57	29459700	585.57
    ///   
    ///   etc
    /// </remarks>
    public class YahooAssetInfoProvider : IAssetIInfoProvider
    {
        static List<SymbolName> _symbolNames;

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

            var fmt = "http://finance.yahoo.com/d/quotes.csv?s={0}&f=l1c1"; // l1=Last Trade, c1=Change
            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 ic = CultureInfo.InvariantCulture;
                    var line = sr.ReadToEnd();
                    var parts = line.Split(',');
                    currChange.Add(double.Parse(parts[0], ic));
                    currChange.Add(double.Parse(parts[1], ic));
                }
            }
            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://ichart.finance.yahoo.com/table.csv?s={0}&a={1}&b={2}&c={3}&d={4}&e={5}&f={6}&g=d&ignore=.csv";
            // example:
            // http://ichart.finance.yahoo.com/table.csv?s=AAPL&a=3&b=12&c=2005&d=2&e=20&f=2012&g=d&ignore=.csv
            // s: 0: stock symbol
            // a: 1: month start
            // b: 2: day start
            // c: 3: year start
            // d: 4: month end
            // e: 5: day end
            // f: 6: year end
            var address = string.Format(fmt, 
                symbol,
                start.Month + 1, start.Day, start.Year, 
                end.Month + 1, end.Day, end.Year);

            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
                    sr.ReadLine();
                    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[6], 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;
        }
    }
}