#!/usr/bin/env python3
"""
Google OAuth2 Re-Authorization (Manual Code Flow)
Kein SSH-Tunnel noetig. Funktioniert mit Hostinger Web Terminal.

Ablauf:
1. Script starten: python3 $HOME/aria/scripts/setup_google_auth_manual.py
2. Den angezeigten Link im Browser oeffnen (PC oder Handy)
3. Google-Konto authorisieren
4. Browser leitet weiter zu http://localhost:8080/callback?code=XXX
   (zeigt "Verbindung abgelehnt" -- das ist OK!)
5. Den kompletten Code aus der URL kopieren und ins Terminal einfuegen
"""
import json
import urllib.parse
import urllib.request
import sys

CREDS_FILE = '/root/.google_credentials.json'
REDIRECT_URI = 'http://localhost:8080/callback'

with open(CREDS_FILE) as f:
    CREDS = json.load(f)

CLIENT_ID = CREDS['client_id']
CLIENT_SECRET = CREDS['client_secret']
SCOPES = ' '.join(CREDS['scopes'])

def build_auth_url():
    params = {
        'client_id': CLIENT_ID,
        'redirect_uri': REDIRECT_URI,
        'response_type': 'code',
        'scope': SCOPES,
        'access_type': 'offline',
        'prompt': 'consent'
    }
    return 'https://accounts.google.com/o/oauth2/v2/auth?' + urllib.parse.urlencode(params)

def exchange_code(code):
    data = urllib.parse.urlencode({
        'code': code,
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
        'redirect_uri': REDIRECT_URI,
        'grant_type': 'authorization_code'
    }).encode()
    req = urllib.request.Request(
        'https://oauth2.googleapis.com/token',
        data=data,
        headers={'Content-Type': 'application/x-www-form-urlencoded'}
    )
    with urllib.request.urlopen(req, timeout=10) as resp:
        return json.loads(resp.read())

def main():
    url = build_auth_url()
    print('\n' + '='*60)
    print('GOOGLE AUTH — SCHRITT 1:')
    print('='*60)
    print('\nOeffne diesen Link im Browser:\n')
    print(url)
    print('\n' + '='*60)
    print('SCHRITT 2:')
    print('='*60)
    print('Nach der Authorisierung leitet Google weiter zu:')
    print('  http://localhost:8080/callback?code=XXXXX...')
    print()
    print('Der Browser zeigt "Verbindung abgelehnt" -- das ist OK!')
    print('Kopiere den "code=..." Teil aus der URL-Leiste.')
    print()

    raw = input('Gib den Code ein (nur den code= Wert, ohne &scope=...): ').strip()

    # URL decode falls noetig + code= prefix entfernen
    if raw.startswith('http'):
        parsed = urllib.parse.urlparse(raw)
        code = urllib.parse.parse_qs(parsed.query).get('code', [raw])[0]
    elif raw.startswith('code='):
        code = raw[5:]
    else:
        code = raw

    code = urllib.parse.unquote(code)
    print(f'\nCode erhalten ({code[:20]}...), tausche gegen Tokens...')

    try:
        result = exchange_code(code)
    except Exception as e:
        print(f'FEHLER beim Token-Austausch: {e}')
        sys.exit(1)

    with open(CREDS_FILE) as f:
        creds = json.load(f)

    creds['access_token'] = result['access_token']
    if 'refresh_token' in result:
        creds['refresh_token'] = result['refresh_token']
        print('Neuer Refresh Token gespeichert.')
    else:
        print('Kein neuer Refresh Token (bestehender bleibt).')

    with open(CREDS_FILE, 'w') as f:
        json.dump(creds, f, indent=2)

    print(f'\nERFOLG: Tokens gespeichert.')
    print(f'Access Token gueltig fuer: ~{result.get("expires_in", 3600)//60} Min')
    print('Cron-Job erneuert den Token alle 30 Min automatisch.')

if __name__ == '__main__':
    main()
