# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/01_wrds/06_ibes_ltg.ipynb.

# %% ../../nbs/01_wrds/06_ibes_ltg.ipynb 3
from __future__ import annotations
from typing import List

import pandas as pd

import pandasmore as pdm
from . import wrds_api

# %% auto 0
__all__ = ['PROVIDER', 'URL', 'LIBRARY', 'TABLE', 'LINK_LIBRARY', 'LINK_TABLE', 'FREQ', 'MIN_YEAR', 'MAX_YEAR',
           'ENTITY_ID_IN_RAW_DSET', 'ENTITY_ID_IN_CLEAN_DSET', 'TIME_VAR_IN_RAW_DSET', 'TIME_VAR_IN_CLEAN_DSET',
           'list_all_vars', 'default_raw_vars', 'parse_varlist', 'get_raw_data']

# %% ../../nbs/01_wrds/06_ibes_ltg.ipynb 4
PROVIDER = 'Refinitiv via WRDS'
URL = 'https://wrds-www.wharton.upenn.edu/pages/get-data/ibes-thomson-reuters/ibes-academic/unadjusted-detail/history/'
LIBRARY = 'ibes'
TABLE = 'detu_epsus'
LINK_LIBRARY = 'wrdsapps_link_crsp_ibes'
LINK_TABLE = 'ibcrsphist'
FREQ = 'M'
MIN_YEAR = 1925
MAX_YEAR = None
ENTITY_ID_IN_RAW_DSET = 'permno'
ENTITY_ID_IN_CLEAN_DSET = 'permno'
TIME_VAR_IN_RAW_DSET = 'date'
TIME_VAR_IN_CLEAN_DSET = f'{FREQ}date'

# %% ../../nbs/01_wrds/06_ibes_ltg.ipynb 5
def list_all_vars() -> pd.DataFrame:
    "Collects names of all available variables from WRDS f`{LIBRARY}.{TABLE}`"

    try:
        db = wrds_api.Connection()
        funda = db.describe_table(LIBRARY,TABLE).assign(wrds_library=LIBRARY, wrds_table=TABLE)
    finally:
        db.close()

    return funda[['name','type','wrds_library','wrds_table']]

# %% ../../nbs/01_wrds/06_ibes_ltg.ipynb 8
def default_raw_vars():
    return ['ticker', 'value', 'fpi', 'anndats', 'fpedats', 'revdats', 'actdats', 'estimator', 'analys', 'pdf']

# %% ../../nbs/01_wrds/06_ibes_ltg.ipynb 9
def parse_varlist(vars: List[str]|str=None, #list of variables requested by user
                  required_vars: List[str] = [], #list of variables that will get downloaded, even if not in `vars`
                  prefix: str='a.', #string to add in front of each variable name when we build the SQL string of variable names
                  ) -> str:
    """Adds required variables to requested variables, validates them, and builds the SQL string with their names"""

    if vars=='*': return f'{prefix}*' 

    # Build full list of variables that will be downloaded
    if vars is None: vars = default_raw_vars()
    if required_vars is None: req_vars = []
    vars =  required_vars + [x for x in vars if x not in required_vars] #in case `vars` already contains some of the required variables

    # Validate variables to be downloaded (make sure that they are in the target database)
    valid_vars = list(list_all_vars().name)
    invalid_vars = [v for v in vars if v not in valid_vars]
    if invalid_vars: raise ValueError(f"These vars are not in the database: {invalid_vars}") 

    return ','.join([f'{prefix}{var_name}' for var_name in vars])

# %% ../../nbs/01_wrds/06_ibes_ltg.ipynb 11
def get_raw_data(vars: List[str]=None, # If None, downloads `default_raw_vars`; `permno`, `ticker`, and `anndats` added by default
            required_vars: List[str] = ['ticker', 'anndats'], #list of variables that will get downloaded, even if not in `vars`
             nrows: int=None, #Number of rows to download. If None, full dataset will be downloaded
             start_date: str=None, # Start date in MM/DD/YYYY format
             end_date: str=None, #End date in MM/DD/YYYY format; if None, defaults to current date
             permno_match_score: tuple=(1,), #accuracy of permno-ibes link. 1-6. 1 is best. use >1 with caution.
             ) -> pd.DataFrame:
    """Downloads `vars` from `start_date` to `end_date` from WRDS `ibes.detu_epsus` library and adds PERMNO from CRSP"""

    wrds_api.validate_dates([start_date, end_date])
    vars = parse_varlist(vars, prefix='a.', required_vars=required_vars)

    sql_string=f"""SELECT {vars}, b.permno
                        FROM {LIBRARY}.{TABLE} AS a
                        LEFT JOIN {LINK_LIBRARY}.{LINK_TABLE} AS b
                        ON a.ticker = b.ticker
                        WHERE a.anndats BETWEEN b.sdate AND b.edate
                                AND fpi='0'
                """
    if permno_match_score is not None: sql_string += r" AND score IN %(permno_match_score)s"
    if start_date is not None: sql_string += r" AND anndats >= %(start_date)s"
    if end_date is not None: sql_string += r" AND anndats <= %(end_date)s"
    if nrows is not None: sql_string += r" LIMIT %(nrows)s"

    return wrds_api.download(sql_string,
                             params={'permno_match_score': permno_match_score,
                                 'start_date':start_date, 'end_date':end_date, 'nrows':nrows})
