import re
import json

from django.core.management.base import BaseCommand
from django.conf import settings

from staff.lib.requests import Session

DEFAULT_CLIENT_ID = '69fa9e824a3f4c6ba6b9616d47344e65'

TOKEN_URL = 'https://oauth.yandex.ru/authorize?response_type=token&client_id={}'
ALLOW_URL = 'https://oauth.yandex.ru/authorize/allow?response_type=token&client_id={}'


class Command(BaseCommand):
    help = 'Update oauth tokens for business taxi accounts'
    args = 'client_id'

    def handle(self, *args, **options):
        client_id = args[0] if args else DEFAULT_CLIENT_ID

        old_credentials = get_credentials(settings.TAXI_CREDENTIALS_PATH)
        new_credentials = {}

        for company, credential in old_credentials.items():
            new_credentials[company] = get_oauth_token(credential, client_id)

        save_credentials(settings.TAXI_CREDENTIALS_PATH, new_credentials)


def get_credentials(path):
    with open(path, 'r') as credentials_file:
        credentials = json.load(credentials_file)
    return credentials


def save_credentials(path, credentials):
    with open(path, 'w') as credentials_file:
        json.dump(credentials, credentials_file)


def get_oauth_token(credential, client_id):
    token_regexp = re.compile(r"access_token=([^&]*)")

    session = Session()
    session.post('https://passport.yandex.ru/passport?mode=auth', data={
        'login': credential['login'],
        'passwd': credential['password'],
    })

    token_page = session.get(TOKEN_URL.format(client_id))
    oauth_token = token_regexp.findall(token_page.url)

    if not oauth_token:
        matching = re.findall(r"name=\"([^\"]*)\" value=\"([^\"]*)\"", token_page.text)
        token_page = session.post(ALLOW_URL.format(client_id), data=dict(set(matching[1:])))
        oauth_token = token_regexp.findall(token_page.url)

    return {
        'login': credential['login'],
        'password': credential['password'],
        'client_id': credential['client_id'],
        'oauth_token': oauth_token[0] if oauth_token else 'BAD CREDENTIALS',
    }
