import requests
from datetime import date
from datetime import timedelta
import datetime
import pandas
import os.path
import shutil
import urllib


def download_data(mode, version, n_max_tries, max_time_per_dl, start, stop, dl_root):
    
    cities = ['NewDehli', 'Chennai', 'Kolkata', 'Mumbai', 'Hyderabad', 'JakartaCentral', 'JakartaSouth', 'Ulaanbaatar', 'HoChiMinhCity', 'Hanoi', 'Bogota', 'Lima', 'AddisAbabaCentral', 'AddisAbabaJacros', 'Kampala', 'Beijing', 'Shanghai', 'Guangzhou', 'Chengdu', 'Shenyang', 'Dhaka', 'AbuDhabi', 'Dubai', 'Pristina', 'KuwaitCity', 'Manama', 'Ashgabat', 'EmbassyKathmandu', 'PhoraDurbarKathmandu', 'Colombo', 'Algiers', 'BuenosAires', 'Sarajevo', 'BanjaLuka', 'Curacao', 'Dhahran', 'Jeddah', 'Riyadh', 'Astana', 'Almaty', 'Tashkent', 'Baghdad', 'Rangoon', 'Bishkek', 'Dushanbe', 'SanJose', 'Islamabad', 'Lahore', 'Karachi', 'Peshawar', 'Amman', 'Vientiane', 'Bamako', 'Antananarivo', 'GuatemalaCity', 'Libreville', 'Abidjan', 'Chisinau', 'Conakry', 'NDjamena', 'Accra', 'KualaLumpur', 'Lagos', 'Abuja', 'Doha', 'Nairobi', 'Baku', 'Cairo', 'Dakar', 'Tijuana', 'Yerevan', 'Kinshasa', 'Ouagadougou', 'SaoPaulo', 'Kigali', 'Lome', 'Asuncion', 'Belmopan', 'Manila', 'Maputo']
    variables = ["PM2.5", "OZONE"]
    base_url = "https://dosairnowdata.org/dos/historical/"

    if mode == 'all':
        bdate = date(2010, 1, 1) # date before record starts
        edate = date.today() + timedelta(days = 365)
        months = ['00']

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

    elif mode == 'nrt':
        bdate = start 
        edate = stop + timedelta(days = 365)
        if start.strftime('%m') == stop.strftime('%m'): # if start and end in one months, only download current month
            months = [start.strftime('%m')]
        else: # if they are in 2 different months, download both of them
            months = [start.strftime('%m'), stop.strftime('%m')] # this month and last month to always cover last 7 days
                    
        os.makedirs('{}/US_EPA_AirNow_DOS/original_files/{}/'.format(dl_root, 'nrt'), exist_ok=True)
        download_location = dl_root+'/US_EPA_AirNow_DOS/original_files/nrt/{}_{}_{}_MTD.csv'
        storage_location = dl_root+'/US_EPA_AirNow_DOS/original_files/nrt/{}_{}_{}_MTD.csv'
        

    else:
        print('time mode inapplicable')

    # create date array, per year
    years = pandas.date_range(bdate, edate, freq='Y').strftime('%Y').tolist()

    print(years)
    print(months)

    for city in cities:

        for variable in variables:

            for year in years:
                
                for month in months:

                    if mode == 'all':
                        url = '{}{}/{}/{}_{}_{}_YTD.csv'.format(base_url, city, year, city, variable, year)
                    elif mode == 'nrt':
                        url = '{}{}/{}/{}_{}_{}_{}_MTD.csv'.format(base_url, city, year, city, variable, year, month)

                    # download 
                    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(city, variable, year+month), 'wb') as outfile:
                                outfile.write(r.content)

                            print('Downloaded {} {} in {}'.format(variable, year+month, city))
                            errcode = r.status_code

                        elif r.status_code == 404:
                            print('No {} {} in {}'.format(variable, year+month, city))
                            errcode = 200

                        elif r.status_code == 300:
                            print('No yet reported {} {} in {}'.format(variable, year+month, city))
                            errcode = 200

                        else:
                            # try again
                            print('Response error {}, attempt {}'.format(r.status_code, n_tries))
                            errcode = r.status_code
                            n_tries += 1

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

            
                    # compare old and new file
                    """if mode == "nrt":

                        same_files = compare_files(download_location.format(city, variable, year+month), storage_location.format(city, variable, year+month))

                        if same_files == True:
                            # delete file in temp
                            os.remove(download_location.format(city, variable, year+month))
                        else:
                            # delete old file, move new file
                            os.remove(storage_location.format(city, variable, year+month))
                            os.rename(download_location.format(city, variable, year+month), storage_location.format(city, variable, year+month))"""
