# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_core.ipynb.

# %% auto 0
__all__ = ['Credentials', 'get']

# %% ../nbs/00_core.ipynb 4
"""
Google OAuth2 login module.
"""

import json
import pickle
from sys import exit
from os import environ
from pathlib import Path
from random import randint
from urllib.error import HTTPError
from urllib.request import urlopen
import google.auth.transport.requests
from googleapiclient.discovery import build
from google.auth.exceptions import RefreshError
from google_auth_oauthlib.flow import InstalledAppFlow


class Credentials:
    """Login to Google services."""

    def __init__(self):
        environ["OAUTHLIB_RELAX_TOKEN_SCOPE"] = "1"
        self.check_url = "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token="

    def get(self, pkl=False, cli=False, scopes=False, file=False):
        if file:
            with open(file, "rb") as handle:
                self.credentials = json.load(handle)
        else:
            self.credentials = json.loads(
                '{"installed":{"client_id":"769904540573-knscs3mhvd56odnf7i8h3al13kiqulft.apps.googleusercontent.com","project_id":"seonotebook-1470430760084","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"D2F1D--b_yKNLrJSPmrn2jik","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}'
            )
        if not scopes:
            scopes = [
                "https://www.googleapis.com/auth/spreadsheets",
                "https://www.googleapis.com/auth/gmail.modify",
                "https://www.googleapis.com/auth/userinfo.email",
                "https://www.googleapis.com/auth/youtube.readonly",
                "https://www.googleapis.com/auth/analytics.readonly",
                "https://www.googleapis.com/auth/webmasters.readonly",
                "https://www.googleapis.com/auth/yt-analytics.readonly",
                "https://ww.googleapis.com/auth/photoslibrary.readonly",
            ]

        if not pkl:
            pkl = "credentials.pkl"
        try:
            self.credentials = self.refresh_token(pkl=pkl, cli=cli, scopes=scopes)
        except Exception as error:
            print(error)
            exit(1)
        return self.credentials

    def refresh_token(self, pkl=False, cli=False, scopes=False):
        """Refresh token to make new logins generally not required."""

        print("Logging in... ", end="")
        try:
            with open(pkl, "rb") as handle:
                self.credentials = pickle.load(handle)
        except FileNotFoundError:
            print("Stored login credentials not found. Login required...")
            self.credentials = self.login(pkl=pkl, cli=cli, scopes=scopes)

        request = google.auth.transport.requests.Request()
        login_required, bad_scope = False, False
        try:
            self.credentials.refresh(request)
        except RefreshError as error:
            print("Refresh error!")
            print(error.args[0])
            login_required = True
            if "scope" in error.args[0]:
                bad_scope = True
        if bad_scope:
            Path(pkl).unlink()
        if login_required:
            self.credentials = self.login(cli)

        # Test if credentials are good
        success = False
        cred_url = self.check_url + self.credentials.token
        try:
            cred_response = urlopen(cred_url)
            success = True
        except Exception as error:
            pass

        if success:
            service = build("oauth2", "v2", credentials=self.credentials)
            user_document = service.userinfo().get().execute()
            full_email = user_document["email"]
            m0, m1 = full_email.split("@")
            stars = randint(9, 17) * "*"
            display_email = f"{m0[0]}{stars}@{m1}"
            print(f"Successfully logged in as {display_email}")

        return self.credentials

    def login(self, pkl=False, cli=False, scopes=False):
        """Start web-based Google OAuth2 login prompt."""

        flow = InstalledAppFlow.from_client_config(self.credentials, scopes)
        if cli:
            self.credentials = flow.run_console()
        else:
            self.credentials = flow.run_local_server()
        with open(pkl, "wb") as handle:
            pickle.dump(self.credentials, handle)
        return self.credentials


def get(pkl=False, cli=False, scopes=False, file=False):
    """Allows simplified ohawf.get() API"""
    return Credentials().get(pkl=pkl, cli=cli, scopes=scopes, file=file)


if __name__ == "__main__":
    print("creds = ohawf.get()  # Default")
    print("creds = ohawf.get(scopes=scopes)  # If you have your own scopes")
    print('creds = ohawf.get(file="client_secret.json*")  # If you\'ve have one')
    print('creds = ohawf.get("creds.pkl")  # For specific pickled credentials file')
