import getpass
import os
import sys
from typing import Optional

from jira import JIRA, JIRAError
import keyring

from rhjira import util

MAX_RETRIES = 6


def _normalize_server(server: str) -> str:
    """Ensure server URL has a scheme (default https)."""
    s = (server or "").strip()
    if s and not s.startswith("http://") and not s.startswith("https://"):
        return "https://" + s
    return s or "https://redhat.atlassian.net"


def connect2jira(server: str, token: str, email: Optional[str] = None) -> JIRA:
    last_error: Optional[JIRAError] = None
    for attempt in range(1, MAX_RETRIES):
        try:
            # For Atlassian Cloud instances, use basic auth with email + token
            # For traditional instances, use token_auth
            if email:
                jira = JIRA(server=server, basic_auth=(email, token))
            else:
                jira = JIRA(server=server, token_auth=token)
            jira.myself()  # test to see if this works
            util.rhjiratax(jira)
            return jira
        except JIRAError as e:
            if attempt == (MAX_RETRIES - 1):
                print(
                    "Error: login failure.  This is likely caused by an invalid token.  Please verify your token and try again." # noqa: E501
                )
                util.handle_jira_error(e, "login")
                sys.exit(1)

    if last_error:
        print("ERROR: unknown login error")
    sys.exit(1)  # Fallback exit if we somehow get here


def login() -> JIRA:
    # check environment variable first (takes priority for testing/overriding)
    token: Optional[str] = os.getenv("JIRA_TOKEN")

    # if not in environment, check the keyring
    if token is None or token == "":
        try:
            token = keyring.get_password("rhjira", getpass.getuser())
        except Exception:
            pass

    if token is None or token == "":
        print("Error: The keyring password could not be read and JIRA_TOKEN was not set.")
        sys.exit(1)

    # Server: env first, then keyring, then default
    server = os.getenv("JIRA_SERVER")
    if not server:
        try:
            server = keyring.get_password("rhjira-server", getpass.getuser())
        except Exception:
            pass
    if not server:
        server = "https://redhat.atlassian.net"

    # For Atlassian Cloud instances, email is required for basic auth
    # Check environment variable first, then fall back to keyring
    email = os.getenv("JIRA_EMAIL")
    if email is None or email == "":
        try:
            email = keyring.get_password("rhjira-email", getpass.getuser())
        except Exception:
            pass

    return connect2jira(server, token, email)


def setpassword() -> None:
    token = getpass.getpass("Enter in token (hit ENTER to abort):")
    if token.strip() == "":
        print("No token entered ... aborting")
        sys.exit(1)

    username = getpass.getuser()

    # Ask for server (optional; for Atlassian Cloud e.g. https://redhat.atlassian.net)
    default_server = "https://redhat.atlassian.net"
    server = input(
        f"Enter Jira server URL (optional, default {default_server}, hit ENTER to skip): "
    ).strip()
    if not server:
        server = default_server

    # Ask for email (optional, for Atlassian Cloud instances)
    email = input("Enter email address for Atlassian Cloud (optional, hit ENTER to skip): ").strip()

    print(f"Attempting to save token to {username}'s keyring ....")
    keyring.set_password("rhjira", username, token)

    print(f"Attempting to save server to {username}'s keyring ....")
    keyring.set_password("rhjira-server", username, server)

    if email:
        print(f"Attempting to save email to {username}'s keyring ....")
        keyring.set_password("rhjira-email", username, email)

    print("testing login with token ....")

    login()

    print(f"Login succeeded.  Token is saved in keyring as ('{username}' on 'rhjira').")
    print(f"Server is saved in keyring as ('{username}' on 'rhjira-server').")
    if email:
        print(f"Email is saved in keyring as ('{username}' on 'rhjira-email').")
