#!/usr/bin/env python3
"""Render resume.yaml -> a .tex file.

Two output flavors are supported:
  --level=short  (default) -> condensed single-page resume.
  --level=full             -> detailed resume; concatenates each list with its
                              `_full` sibling (e.g. bullets + bullets_full).

The LaTeX preamble (styles, macros, page layout) lives inline as PREAMBLE
below; tweak typography or colors there. Content is read from resume.yaml.
"""
import argparse
import os
import yaml

HERE = os.path.dirname(os.path.abspath(__file__))
DATA = os.path.join(HERE, "resume.yaml")
DEFAULT_OUT = {
    "short": os.path.join(HERE, "MikeEberlein_Resume.tex"),
    "full":  os.path.join(HERE, "MikeEberlein_Resume_Detailed.tex"),
}

PREAMBLE = r"""% Mike Eberlein — single-page resume (generated from resume.yaml).
% Build:  lualatex MikeEberlein_Resume.tex   (run twice for stable layout)
% Do not edit by hand — re-run `python3 render_tex.py` after changing resume.yaml.
%
% Fonts: Roboto, loaded directly from ./fonts/static/ via fontspec. Requires
% lualatex (or xelatex). This makes the build self-contained — no dependency
% on TeX Live's bundled `roboto` package.

\documentclass[letterpaper,10pt]{extarticle}

\usepackage{fontspec}
\setmainfont{Roboto}[
  Path           = fonts/static/,
  Extension      = .ttf,
  UprightFont    = *-Regular,
  ItalicFont     = *-Italic,
  BoldFont       = *-Bold,
  BoldItalicFont = *-BoldItalic,
  Ligatures      = NoCommon,            % keep fi/fl as two letters so PDF text search / ATS works
]
\newfontfamily\RobotoLight{Roboto}[
  Path=fonts/static/, Extension=.ttf,
  UprightFont=*-Light, ItalicFont=*-LightItalic,
  Ligatures=NoCommon,
]
\newfontfamily\RobotoMedium{Roboto}[
  Path=fonts/static/, Extension=.ttf,
  UprightFont=*-Medium, BoldFont=*-Bold,
  Ligatures=NoCommon,
]

\usepackage{microtype}
\usepackage[letterpaper,margin=0.5in,top=0.35in,bottom=0.3in]{geometry}
\usepackage[dvipsnames]{xcolor}
\usepackage{titlesec}
\usepackage{enumitem}
\usepackage{hyperref}
\usepackage{ragged2e}
\usepackage{parskip}

\definecolor{accent}{HTML}{1F3864}
\definecolor{body}{HTML}{222222}
\definecolor{muted}{HTML}{555555}
\color{body}

\hypersetup{colorlinks=true, urlcolor=accent, linkcolor=accent}

\setlength{\parindent}{0pt}
\setlength{\parskip}{0pt}
\linespread{1.0}
\pagestyle{empty}

\titleformat{\section}
  {\color{accent}\RobotoMedium\bfseries\large}
  {}{0pt}
  {\MakeUppercase}
\titlespacing*{\section}{0pt}{4pt}{0pt}
\newcommand{\sectionrule}{\vspace{-4pt}{\color{accent}\rule{\linewidth}{0.5pt}}\par\vspace{1pt}}

\newcommand{\job}[2]{%
  \vspace{3pt}%
  \noindent\textbf{#1}\hfill\textbf{#2}\par\vspace{0pt}%
}
\newcommand{\role}[2]{%
  \vspace{1pt}%
  \noindent\textit{\textcolor{muted}{#1}}\hfill\textit{\textcolor{muted}{#2}}\par%
}
\newcommand{\subrole}[2]{%
  \vspace{1pt}%
  \noindent\hspace{0.18in}#1\hfill\textit{\textcolor{muted}{#2}}\par%
}

\newlist{bullets}{itemize}{2}
\setlist[bullets]{leftmargin=0.22in, itemsep=0pt, topsep=0pt, parsep=0pt, label={\textbullet}}
\newlist{subbullets}{itemize}{2}
\setlist[subbullets]{leftmargin=0.42in, itemsep=0pt, topsep=0pt, parsep=0pt, label={\textbullet}, before=\color{muted}}

\newcommand{\name}[1]{%
  \begin{center}%
    {\color{accent}\fontseries{l}\fontsize{26}{30}\selectfont #1}%
  \end{center}%
  \vspace{10pt}%
}
\newcommand{\contact}[1]{%
  \begin{center}\textcolor{muted}{\small #1}\end{center}%
  \vspace{2pt}%
}
"""

# LaTeX special characters that need escaping in content text.
LATEX_ESCAPES = {
    "&":  r"\&",
    "%":  r"\%",
    "$":  r"\$",
    "#":  r"\#",
    "_":  r"\_",
    "{":  r"\{",
    "}":  r"\}",
    "~":  r"\textasciitilde{}",
    "^":  r"\textasciicircum{}",
    "\\": r"\textbackslash{}",
}

def tex_escape(s: str) -> str:
    out = []
    for ch in s:
        out.append(LATEX_ESCAPES.get(ch, ch))
    return "".join(out)

def merged(item, key, level):
    """Return item[key] for short, or item[key] + item[key + '_full'] for full."""
    base = item.get(key) or []
    if level == "full":
        base = list(base) + list(item.get(key + "_full") or [])
    return base

def emit_bullets(items, env="bullets"):
    lines = [f"\\begin{{{env}}}"]
    for b in items:
        lines.append(f"  \\item {tex_escape(b)}")
    lines.append(f"\\end{{{env}}}")
    return "\n".join(lines)

def render(data, level="short") -> str:
    out = [PREAMBLE, ""]
    out.append(r"\begin{document}")
    out.append("")
    h = data["header"]
    out.append(f"\\name{{{tex_escape(h['name'])}}}")
    contact = (
        f"{tex_escape(h['tagline'])} \\textbullet{{}} "
        f"\\href{{mailto:{h['email']}}}{{{tex_escape(h['email'])}}}"
    )
    out.append(f"\\contact{{{contact}}}")
    out.append("")
    out.append("{\\justifying\\noindent")
    out.append(tex_escape(data["summary"].strip()) + r"\par}")
    out.append("")
    out.append(r"\section{Experience}\sectionrule")
    out.append("")
    for company in merged(data, "experience", level):
        out.append(f"\\job{{{tex_escape(company['company'])}}}{{{tex_escape(company['dates'])}}}")
        for role in merged(company, "roles", level):
            out.append(f"\\role{{{tex_escape(role['title'])}}}{{{tex_escape(role['dates'])}}}")
            subroles = merged(role, "subroles", level)
            if subroles:
                out.append("")
                for sr in subroles:
                    out.append(f"\\subrole{{{tex_escape(sr['title'])}}}{{{tex_escape(sr['dates'])}}}")
                    out.append(emit_bullets(merged(sr, "bullets", level), env="subbullets"))
                    out.append("")
            else:
                bullets = merged(role, "bullets", level)
                if bullets:
                    out.append(emit_bullets(bullets, env="bullets"))
                    out.append("")
    out.append(r"\section{Education}\sectionrule")
    out.append("")
    for ed in merged(data, "education", level):
        out.append(f"\\job{{{tex_escape(ed['school'])}}}{{{tex_escape(ed['dates'])}}}")
        out.append(emit_bullets(merged(ed, "bullets", level), env="bullets"))
        out.append("")
    out.append(r"\section{Certifications}\sectionrule")
    out.append("")
    out.append(" \\textbullet{} ".join(tex_escape(c) for c in merged(data, "certifications", level)))
    out.append("")
    out.append(r"\end{document}")
    return "\n".join(out) + "\n"

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--level", choices=["short", "full"], default="short")
    ap.add_argument("--output", default=None,
                    help="Output .tex path (default: MikeEberlein_Resume.tex / MikeEberlein_Resume_Detailed.tex)")
    args = ap.parse_args()

    out_path = args.output or DEFAULT_OUT[args.level]
    with open(DATA, "r", encoding="utf-8") as f:
        data = yaml.safe_load(f)
    tex = render(data, level=args.level)
    with open(out_path, "w", encoding="utf-8") as f:
        f.write(tex)
    print(f"wrote {out_path}  (level={args.level})")

if __name__ == "__main__":
    main()
