import requests
import typer
import time
import re
import pathlib
import hashlib
import sys
from rich.console import Console
from rich.highlighter import RegexHighlighter

LINK_PATTERN = (
    r"(?:https://kdrive\.infomaniak\.com/app/collaborate/)?([0-9]+)/([0-9a-f-]+)"
)
TOKEN_URL = "https://kdrive.infomaniak.com/2/app/{kdrive_id}/dropbox/{box_uuid}/token"
USER_URL = "https://kdrive.infomaniak.com/2/app/{kdrive_id}/dropbox/{box_uuid}/user"
UPLOAD_URL = "https://kdrive.infomaniak.com/2/app/{kdrive_id}/dropbox/{box_uuid}/upload"


class KDUError(Exception):
    pass


class EmailHighlighter(RegexHighlighter):
    """Apply style to anything that looks like an email."""

    # base_style = "progress.elapsed"
    highlights = [r"(?P<dim>`.*?`)"]


def _raise_for_status(resp: requests.Response, *args, **kwargs):
    try:
        resp.raise_for_status()
    except requests.exceptions.HTTPError as e:
        e.add_note(f"content: {resp.text}")
        raise KDUError() from e


def main(
    kdrive_share_link: str,
    file: pathlib.Path,
    first_name="kdrive_uploader",
    last_name="kdrive_uploader",
    email="kdrive_uploader@ik.me",
):
    # check file
    if not file.exists():
        raise KDUError(f"File `{file.absolute()}` does not exist.")

    # parse the link
    match = re.match(LINK_PATTERN, kdrive_share_link)
    if not match:
        raise KDUError(
            f"Could not match link `{kdrive_share_link}`. It must either be a full kDrive drop box link `https://kdrive.infomaniak.com/app/collaborate/0000000/00000000-0000-0000-0000-000000000000` or just the ids segments `0000000/00000000-0000-0000-0000-000000000000`"
        )
    kdrive_id = match.group(1)
    box_uuid = match.group(2)

    session = requests.sessions.Session()
    session.hooks = {"response": _raise_for_status}

    # get the client token
    token_url = TOKEN_URL.format(kdrive_id=kdrive_id, box_uuid=box_uuid)
    token_resp = session.get(token_url)
    token_data = token_resp.json()
    token = token_data["data"]["uuid"]
    session.headers["Ik-Dropbox-Token"] = token

    # set the user
    user_url = USER_URL.format(kdrive_id=kdrive_id, box_uuid=box_uuid)
    user_payload = dict(
        first_name=first_name,
        last_name=last_name,
        email=email,
    )
    session.post(user_url, json=user_payload)

    # do the upload
    upload_url = UPLOAD_URL.format(kdrive_id=kdrive_id, box_uuid=box_uuid)
    upload_params = dict(
        conflict="replace",
        directory_id=1,
        directory_path="",
        file_name=file.name,
        total_size=file.stat().st_size,
        last_modified_at=int(time.time()),
        total_chunk_hash=f"sha512:{hashlib.sha512(file.read_bytes()).hexdigest()}",
        chunk_number=1,
        chunk_size=file.stat().st_size,
        client_token=token,
    )
    session.post(upload_url, params=upload_params, data=file.open("rb"))

    print("Success !")


def run_cli():
    try:
        typer.run(main)
    except KDUError as e:
        console = Console(highlighter=EmailHighlighter())
        console.print(e, style="traceback.title")
        sys.exit(1)


if __name__ == "__main__":
    run_cli()
