#!/usr/bin/env python3

import os, pathlib
import gkeepapi
import frontmatter
import click
from pathvalidate import sanitize_filename


def login(user_email: str, password: str) -> gkeepapi.Keep:
    keep = gkeepapi.Keep()
    try:
        keep.login(user_email, password)
    except Exception:
        raise click.BadParameter("Login failed.")

    return keep


def process_note(note: gkeepapi._node.Note) -> frontmatter.Post:
    metadata = {
        "id": note.id,
        "title": note.title,
        "pinned": note.pinned,
        "trashed": note.trashed,
        "deleted": note.deleted,
        "color": note.color.name,
        "type": note.type.name,
        "parent_id": note.parent_id,
        "sort": note.sort,
        "url": note.url,
        "timestamps": {
            "created": note.timestamps.created.timestamp(),
            "edited": note.timestamps.edited.timestamp(),
            "updated": note.timestamps.updated.timestamp(),
        },
    }

    if note.timestamps.trashed:
        metadata["timestamps"]["trashed"] = note.timestamps.trashed.timestamp()
    if note.timestamps.deleted:
        metadata["timestamps"]["deleted"] = note.timestamps.deleted.timestamp()

    return frontmatter.Post(note.text, handler=None, **metadata)


@click.command()
@click.option(
    "--directory",
    "-d",
    default="./gkeep-export",
    help="Output directory for exported notes",
)
@click.option(
    "--user",
    "-u",
    default=lambda: os.environ.get("GKEEP_USER"),
    prompt=True,
    help="Google account email",
)
@click.option(
    "--password",
    "-p",
    default=lambda: os.environ.get("GKEEP_PASSWORD"),
    prompt=True,
    help="Google account password",
    hide_input=True,
)
def main(directory, user, password):
    """A simple utility to export google keep notes to markdown files with metadata stored as a frontmatter header."""
    outpath = pathlib.Path(directory).resolve()

    click.echo(f"Output directory: {outpath}")
    click.echo("Logging in.")
    keep = login(user, password)

    click.echo("Beginning note export.")
    
    if not outpath.exists():
        click.echo("output directory does not exist, creating.")
        outpath.mkdir(parents=True)

    notes = keep.all()
    note_count = 0
    for note in notes:
        note_count += 1
        click.echo(f"Processing note #{note_count}")
        post = process_note(note)

        outfile = (
            outpath
            / f'{sanitize_filename(f"{note_count:04} - " + post.metadata["title"],max_len=135)} .md'
        )
        with outfile.open("wb") as fp:
            frontmatter.dump(post, fp)

    click.echo("Done.")


if __name__ == "__main__":
    main()