
import os
import errno
import requests
import json
import datetime

import config
import blizzard
import spec

def log(*data):
    print(datetime.datetime.now(), '|', *data)

class Updater(object):
    def __init__(self):
        self.http = requests.Session()
        self.credentials = blizzard.get_credentials(config.pwd)

    def region_oauth(self, region: str) -> dict:
        api = self.http.post(f"{blizzard.get_bnet_host(region)}/oauth/token", data={'grant_type': 'client_credentials'}, auth=self.credentials)
        oauth = api.json()
        #log(region, oauth)
        api.raise_for_status()
        return oauth

    def api_call(self, url: str) -> requests.Response:
        api = self.http.get(url) #, headers={'Authorization': f"Authorization: Token {access_token}"})
        api.raise_for_status()
        return api

    def create_dst(self, dst: str):
        try:
            os.makedirs(os.path.dirname(dst))
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise

    def save(self, dst, content):
        with open(dst, 'w+') as f:
            f.write(json.dumps(content.json(), indent=4))

    def iterate_index(self):
        for region in spec.regions:
            # access token for region
            try:
                oauth = self.region_oauth(region['code'])
                access_token = oauth['access_token']
            except (requests.exceptions.HTTPError, KeyError) as e:
                log(region, type(e), e)
                continue

            # loop every api
            for api in spec.apis:
                if not 'index' in api or not api['index']:
                    continue

                for locale in region['locales']:
                    # retail or classic
                    for namespace in api['namespaces']:
                        try:
                            dst = f"{config.raw}/{region['code']}/{locale}/{api['path'].replace('/', '_')}.{namespace}.json"

                            url = f"{blizzard.get_api_host(region['code'])}{api['path']}"
                            url += f"?namespace={namespace}-{region['code']}&locale={locale}&access_token={access_token}"
                            response = self.api_call(url)

                            self.create_dst(dst)
                            self.save(dst, response)

                        except requests.exceptions.HTTPError as e:
                            log(e)
                            continue

if __name__ == "__main__":
    updater = Updater()
    updater.iterate_index()
    #updater.iterate_links()
