# -*- coding: UTF-8 -*-
# pylint: disable=protected-access
import unittest
from datetime import date, time

from landscape.finance import database, dates
from landscape.finance.quotes import futures


TEST_DB_NAME = 'test.db'


class BaseFuturesTestCase(unittest.TestCase):

    def setUp(self):
        database.drop_db(TEST_DB_NAME)

    def tearDown(self):
        database.drop_db(TEST_DB_NAME)

    def _check_quotes(self, quotes, symbol, check_date):
        self.assertGreater(len(quotes), 0)
        self.assertTrue(all(isinstance(item, futures.FutureQuote) \
                            for item in quotes))
        self.assertTrue(all(item.symbol == symbol for item in quotes))
        self.assertTrue(all(item.date == check_date for item in quotes))
        self.assertTrue(all(0 < item.close < 200 for item in quotes))

    def _check_database_quotes(self, symbol, total, check_date, total_date):
        with database.connect_db(TEST_DB_NAME) as db:
            db.execute('SELECT COUNT(*) FROM futures WHERE symbol=?;', [symbol])
            self.assertEqual(db.fetchall(), [(total,)])
        if total > 0:
            database_quotes = futures.query_historical(
                symbol, check_date, TEST_DB_NAME)
            self.assertEqual(len(database_quotes), total_date)
            self._check_quotes(database_quotes, symbol, check_date)


class DatabaseTest(BaseFuturesTestCase):

    def test_save_and_factory(self):
        quote1 = futures.FutureQuote(
            'XXX', date(2015, 3, 4), date(2015, 1, 2), time(15, 16), 17.2)
        with database.connect_db(TEST_DB_NAME) as db:
            db.row_factory = futures.quote_factory
            futures.save_quote(db, quote1)
            db.execute('SELECT * FROM futures;')
            quote2 = db.fetchone()
        self.assertEqual(quote1, quote2)


class RawFetchTest(BaseFuturesTestCase):

    def test_fetch_realtime_data(self):
        raw_text = futures._fetch_realtime_data('VX')
        self.assertGreaterEqual(raw_text.find('<html'), 0)
        self.assertGreater(len(raw_text), 200000)

    def test_fetch_realtime_data_not_allowed_symbol(self):
        self.assertRaises(AssertionError, futures._fetch_realtime_data, 'ABC')

    def test_fetch_historical_data(self):
        raw_text = futures._fetch_historical_data('VX', date(2015, 12, 16))
        self.assertTrue(raw_text.startswith('CFE data is compiled for'))
        self.assertGreater(len(raw_text), 1000)

    def test_fetch_historical_data_not_allowed_symbol(self):
        self.assertRaises(
            AssertionError, futures._fetch_historical_data,
            'ABC', date(2015, 12, 16))


class ParseDataTest(BaseFuturesTestCase):

    def test_parse_realtime_data(self):
        test_data = """<div class="component">
    <div class="left">
        <a name="VX"></a>
        <h3>VX&nbsp;- &nbsp;CBOE S&amp;P 500 Volatility Index (VIX) Futures</h3>
    </div>
    <div class="table-wrapper">
        <table class="table  oddeven  padvertical  padhorizontal inner-cellborders">
            <tbody>
                <tr>
                    <td><a href="ssfquote.aspx?ticker=VIX/F6" title="VIX/F6">VIX/F6</a></td>
                    <td style="text-align:right"><span>01/20/2016</span>
                    <td style="text-align:right"><span>24.15</span></td>
                    <td style="text-align:right"><span data-numericcolor="-0.575">-0.575</span></td>
                    <td style="text-align:right"><span>25.30</span></td>
                    <td style="text-align:right"><span>24.05</span></td>