#!/usr/bin/env python3
"""
Plot memory timeline for MemConstrainedWriter.
Uses only flush_before/flush_after points to draw clean sawtooth envelope.
"""

import os
import csv
import numpy as np
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

BASE = os.path.dirname(os.path.abspath(__file__))

plt.rcParams.update({
    "font.family": "sans-serif",
    "font.sans-serif": ["Songti SC", "Heiti TC", "STHeiti", "PingFang HK",
                         "Hiragino Sans GB", "DejaVu Sans"],
    "axes.unicode_minus": False,
    "font.size": 11,
    "axes.labelsize": 12,
    "axes.titlesize": 13,
    "legend.fontsize": 9,
    "figure.dpi": 150,
})


def mb(v):
    return int(v) / (1024 * 1024)


def load_envelope(detail_csv, keep_every=1):
    """Extract flush envelope: flush_before (peak) and flush_after (valley) pairs.
    Also keep rotate and final events. Downsample flush pairs by keep_every."""
    rows = list(csv.DictReader(open(detail_csv)))
    pts = []
    flush_idx = 0
    for r in rows:
        evt = r["event"]
        if evt in ("flush_before", "flush_after"):
            flush_idx += 1
            if flush_idx % (keep_every * 2) <= 1:  # keep every Nth pair
                pts.append(r)
        elif evt in ("rotate_before", "rotate_after", "final_close"):
            pts.append(r)
        elif evt == "batch" and len(pts) == 0:
            pts.append(r)  # keep first point
    return pts


def draw_timeline(ax, pts, mem_limit_mb, title=None):
    # M_init: budget reservation used by MemConstrainedWriter
    M_INIT_MB = 900.0 / 1024  # 900 KB

    x = np.array([int(p["rows_written"]) / 1e6 for p in pts])
    m_data = np.array([mb(p["m_data_direct"]) for p in pts])
    m_meta = np.array([mb(p["m_meta_direct"]) for p in pts])

    # Stacked: M_init (base) + M_meta + M_data
    y_init = np.full_like(x, M_INIT_MB)
    y_meta_top = y_init + m_meta
    y_total = y_meta_top + m_data

    ax.fill_between(x, 0, y_init, alpha=0.15, color="#64748b",
                    linewidth=0, label="$M_{init}$")
    ax.fill_between(x, y_init, y_meta_top, alpha=0.30, color="#f59e0b",
                    linewidth=0, label="$M_{meta}$")
    ax.fill_between(x, y_meta_top, y_total, alpha=0.30, color="#2563eb",
                    linewidth=0, label="$M_{data}$")
    ax.plot(x, y_total, color="#1e293b", linewidth=0.5, alpha=0.7)

    # M_limit line
    ax.axhline(y=mem_limit_mb, color="#dc2626", linestyle="--", linewidth=2,
               alpha=0.9, label=f"$M_{{limit}}$ = {mem_limit_mb} MB")

    # Rotation markers
    rotate_xs = [int(p["rows_written"]) / 1e6
                 for p in pts if p["event"] == "rotate_before"]
    for i, rx in enumerate(rotate_xs):
        ax.axvline(x=rx, color="#7c3aed", linestyle="-", linewidth=1.5, alpha=0.4)
        y_pos = mem_limit_mb * (0.92 if i % 2 == 0 else 0.84)
        ax.text(rx + 0.3, y_pos, f"R{i+1}", fontsize=9, color="#7c3aed",
                fontweight="bold")

    ax.set_xlabel("写入行数（百万）")
    ax.set_ylabel("内存（MB）")
    ax.set_ylim(0, mem_limit_mb * 1.15)
    ax.set_xlim(0, max(x) * 1.02)
    ax.legend(loc="center right", framealpha=0.9)
    ax.grid(True, alpha=0.2)
    if title:
        ax.set_title(title)


def plot_single(detail_csv, mem_limit_mb, out_path, keep_every=3):
    pts = load_envelope(detail_csv, keep_every=keep_every)
    fig, ax = plt.subplots(figsize=(10, 4))
    draw_timeline(ax, pts, mem_limit_mb,
                  title=f"内存受限写入时间线"
                        f"（$M_{{limit}}$ = {mem_limit_mb} MB）")
    fig.tight_layout()
    fig.savefig(out_path)
    print(f"  -> {out_path}  ({len(pts)} points)")
    plt.close(fig)


def plot_comparison(out_path):
    configs = [
        ("write_budget_detail_2MB.csv", 2, "2 MB 预算（文件轮转）", 3),
        ("write_budget_detail_8MB.csv", 8, "8 MB 预算（单文件）", 2),
    ]
    fig, axes = plt.subplots(1, 2, figsize=(13, 4))

    for ax, (csv_file, limit, title, ke) in zip(axes, configs):
        path = os.path.join(BASE, "E3_4_write_budget", csv_file)
        pts = load_envelope(path, keep_every=ke)
        draw_timeline(ax, pts, limit, title=title)

    fig.suptitle("内存安全写入：两级控制实际运行",
                 fontsize=14, y=1.01)
    fig.tight_layout()
    fig.savefig(out_path, bbox_inches="tight")
    print(f"  -> {out_path}")
    plt.close(fig)


if __name__ == "__main__":
    print("=== Flush Timeline Plots ===")
    plot_single(
        os.path.join(BASE, "E3_4_write_budget", "write_budget_detail_2MB.csv"),
        2, os.path.join(BASE, "F3_flush_timeline_2MB.pdf"), keep_every=3)
    plot_comparison(os.path.join(BASE, "F3_flush_timeline_compare.pdf"))
    print("Done.")
