import requests
import time
import pandas as pd
from datetime import date
from datetime import timedelta
import os.path


def download_data(mode, version, n_max_tries, max_time_per_dl, start, stop, dl_root):

    base_url = 'https://quotsoft.net/air/data'

    if mode == 'all':
        bdate = date(2013, 12, 1) # date before record starts
        edate = date.today()

        os.makedirs('{}/BJMEMC/original_files/{}/'.format(dl_root, version), exist_ok=True)
        download_location = dl_root+'/BJMEMC/original_files/'+version+'/{}/{}.csv'

    elif mode == 'nrt':
        bdate = start # if code is run after 2 am, data from previous day will be available
        edate = stop

        os.makedirs('{}/BJMEMC/original_files/nrt/'.format(dl_root), exist_ok=True)
        download_location = dl_root+'/BJMEMC/original_files/nrt/{}/{}.csv'

    else:
        print('time mode inapplicable')


    # create date array, daily; format YYYYMMDD
    dates = pd.date_range(bdate, edate, freq='d').strftime('%Y%m%d').tolist()

    # download
    for day in dates:
        url = '{}/beijing_all_{}.csv'.format(base_url, day)
        n_tries = 0
        errcode = 999

        while (n_tries < n_max_tries) and (errcode != 200):
            r = requests.get(url, timeout=max_time_per_dl)
            if r.status_code == 200:
                with open(download_location.format('all', day), 'wb') as file:
                    file.write(r.content)
                #urllib.request.urlretrieve(url, download_location.format('all', day))
                print('Downloaded {}'.format(url))
                errcode = r.status_code

            elif r.status_code == 404:
                print('No {}'.format(url))
                errcode = 200 #skip
            else:
                # try again
                print('Response error {}, attempt {}'.format(r.status_code, n_tries))
                errcode = r.status_code
                n_tries += 1
                time.sleep(n_tries ** 2) # wait a lil more every time 

        if n_tries == n_max_tries:
            print('Failed downloading {} {} times in {} seconds, error code {}'.format(url, n_tries, max_time_per_dl, errcode))
        

        url = '{}/beijing_extra_{}.csv'.format(base_url, day)
        n_tries = 0
        errcode = 999

        while (n_tries < n_max_tries) and (errcode != 200):
            r = requests.get(url, timeout=max_time_per_dl)
            if r.status_code == 200:
                with open(download_location.format('extra', day), 'wb') as file:
                    file.write(r.content)
                #urllib.request.urlretrieve(url, download_location.format('extra', day))
                print('Downloaded {}'.format(url))
                errcode = r.status_code
            elif r.status_code == 404:
                print('No {}'.format(url))
                errcode = 200 #skip
            else:
                # try again
                print('Response error {}, attempt {}'.format(r.status_code, n_tries))
                errcode = r.status_code
                n_tries += 1
                time.sleep(n_tries ** 2) # wait a lil more every time 

        if n_tries == n_max_tries:
            print('Failed downloading {} {} times in {} seconds, error code {}'.format(url, n_tries, max_time_per_dl, errcode))
        
        time.sleep(1)

        """
        # reorganize files per component
        components_all = ['AQI', 'PM2.5', 'PM2.5_24h', 'PM10', 'PM10_24h']
        components_extra = ['SO2', 'SO2_24h', 'NO2', 'NO2_24h','O3', 'O3_24h', 'CO', 'CO_24h']

        if mode == "nrt":
            for component in components_all:
                # all
                og_file = pd.read_csv(download_location.format('all', day))
                comp = og_file[og_file["type"] == component]

                output_path = download_location.format('all', component+"_{}".format(dates[0][0:4]))
                comp.to_csv(output_path, mode='a', header=not os.path.exists(output_path), index=False)

                # check if there is data doubled
                new_file = pd.read_csv(output_path).drop_duplicates()
                new_file.to_csv(output_path, index=False)

            os.remove(download_location.format('all', day))


            for component in components_extra:
                # extra
                og_file = pd.read_csv(download_location.format('extra', day))
                comp = og_file[og_file["type"] == component]

                output_path = download_location.format('extra', component+"_{}".format(dates[0][0:4]))
                comp.to_csv(output_path, mode='a', header=not os.path.exists(output_path), index=False)

                # check if there is data doubled
                new_file = pd.read_csv(output_path).drop_duplicates()
                new_file.to_csv(output_path, index=False)


            # delete original files
            os.remove(download_location.format('extra', day))"""
