"""Render case-study figures from an adjacent published activity.json snapshot.

Install matplotlib==3.10.8. Run: python reproduce-charts.py /path/to/activity.json
The data is repository history; PR intervals are not agent execution intervals.
"""
import json
import sys
from collections import Counter
from datetime import datetime, timezone
from pathlib import Path

import matplotlib
matplotlib.use('Agg')
import matplotlib.dates as dates
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator

source = Path(sys.argv[1])
data = json.loads(source.read_text())
BG, INK, MUTED, GRID = '#111317', '#eeede7', '#b4b5af', '#34373b'
GREEN, BLUE, PURPLE, ORANGE = '#bada74', '#87bdf9', '#ba9df3', '#e3ad73'
plt.rcParams.update({'figure.facecolor': BG, 'axes.facecolor': BG, 'savefig.facecolor': BG,
    'text.color': INK, 'axes.labelcolor': MUTED, 'xtick.color': MUTED, 'ytick.color': MUTED,
    'axes.edgecolor': GRID, 'font.family': 'DejaVu Sans', 'font.size': 12,
    'svg.fonttype': 'path', 'svg.hashsalt': 'descant-case-study-v1'})

def date(value):
    return datetime.fromisoformat(value.replace('Z', '+00:00')).astimezone(timezone.utc)

def frame(title, ylabel):
    fig, ax = plt.subplots(figsize=(13, 5.6))
    fig.subplots_adjust(left=.08, right=.96, top=.82, bottom=.19)
    ax.set_title(title, loc='left', fontsize=21, weight='bold', pad=24)
    ax.spines[['top', 'right']].set_visible(False)
    ax.grid(axis='y', color=GRID, linewidth=.7)
    ax.set_ylabel(ylabel)
    ax.yaxis.set_major_locator(MaxNLocator(integer=True))
    locator = dates.AutoDateLocator(minticks=4, maxticks=7)
    ax.xaxis.set_major_locator(locator)
    ax.xaxis.set_major_formatter(dates.ConciseDateFormatter(locator))
    return fig, ax

def curve(ax, times, label, color):
    counts = Counter(times)
    ordered = sorted(counts)
    if not ordered:
        return
    total, values = 0, []
    for time in ordered:
        total += counts[time]
        values.append(total)
    ax.step(ordered, values, where='post', color=color, linewidth=3,
            label=f'{label} · {total:,}')
    ax.scatter(ordered[-1], values[-1], color=color, s=55, zorder=5)

def finish(fig, ax, name, footnote):
    ax.set_ylim(bottom=0)
    ax.legend(loc='upper left', frameon=False, labelcolor=INK, fontsize=11)
    ax.margins(x=.025)
    fig.text(.08, .045, footnote, fontsize=10, color=MUTED)
    fig.savefig(source.parent / name, metadata={'Date': None})
    plt.close(fig)

fig, ax = frame('Issues created and closed', 'Cumulative issues')
issues = data['issues']
curve(ax, [date(x['createdAt']) for x in issues], 'Created', BLUE)
curve(ax, [date(x['closedAt']) for x in issues if x['closedAt'] and x['reason']=='completed'], 'Closed as completed', GREEN)
curve(ax, [date(x['closedAt']) for x in issues if x['closedAt']], 'All closed', PURPLE)
finish(fig, ax, 'issue-progress.svg', 'UTC · Current closure state, positioned at final close date · Each line stops at its last event')

fig, ax = frame('Merged work over time', 'Cumulative pull requests')
prs = data['pullRequests']
curve(ax, [date(x['mergedAt']) for x in prs if x['mergedAt']], 'Merged', GREEN)
curve(ax, [date(x['createdAt']) for x in prs], 'Opened', BLUE)
finish(fig, ax, 'work-progress.svg', 'UTC · Repository pull requests · Each line stops at its last event; no projected completions')

fig, ax = frame('Published review findings', 'Finding reports')
review = data['reviewFindings']
colors = {'P1': ORANGE, 'P2': BLUE, 'P3': PURPLE, 'other': MUTED}
counts = Counter(x['priority'] for x in review)
names = [x for x in colors if counts[x]]
bars = ax.bar(names, [counts[x] for x in names], color=[colors[x] for x in names], width=.55)
ax.xaxis.set_major_locator(plt.FixedLocator(range(len(names))))
ax.xaxis.set_major_formatter(plt.FixedFormatter(names))
ax.bar_label(bars, labels=[f'{counts[x]:,}' for x in names], padding=7, fontsize=17, color=INK)
ax.set_ylim(0, max(counts.values(), default=1)*1.22)
fig.text(.08,.045,'Original reviewer priorities · Reports may repeat a defect · Not a count of unique bugs or verified fixes',fontsize=10,color=MUTED)
fig.savefig(source.parent/'review-findings.svg',metadata={'Date':None});plt.close(fig)
print(json.dumps({'source':str(source),'issues':len(issues),'pullRequests':len(prs),'findingReports':len(review),'figures':3}))
