"""
Act as a wrapper around pandas_datareader and write the responses to the
database to be accessed later.
"""
import datetime as dt
import logging
from typing import Dict, Iterable, Union, Tuple

import numpy as np
import pandas as pd
import pandas_datareader as pdr
from arctic.date import DateRange
from arctic.exceptions import NoDataFoundException
from pandas.tseries.offsets import BDay
from pandas_datareader._utils import RemoteDataError

import pytech.utils.dt_utils as dt_utils
import pytech.utils.pandas_utils as pd_utils
from pytech.decorators.decorators import write_chunks
from pytech.mongo import ARCTIC_STORE
from pytech.mongo.barstore import BarStore
from pytech.utils.exceptions import DataAccessError
from pytech.data._holders import DfLibName

logger = logging.getLogger(__name__)

ticker_input = Union[Iterable, str, pd.DataFrame]
range_type = Union[pd.DatetimeIndex, DateRange]


YAHOO = 'yahoo'
GOOGLE = 'google'
FRED = 'fred'
FAMA_FRENCH = 'famafrench'


class BarReader(object):
    """Read and write data from the DB and the web."""

    def __init__(self, lib_name: str):
        self.lib_name = lib_name

        if lib_name not in ARCTIC_STORE.list_libraries():
            # create the lib if it does not already exist
            ARCTIC_STORE.initialize_library(lib_name,
                                            BarStore.LIBRARY_TYPE)

        self.lib = ARCTIC_STORE[self.lib_name]

    def get_data(self,
                 tickers: ticker_input,
                 source: str = GOOGLE,
                 start: dt.datetime = None,
                 end: dt.datetime = None,
                 check_db: bool = True,
                 filter_data: bool = True,
                 **kwargs) -> Union[pd.DataFrame, Dict[str, pd.DataFrame]]:
        """