"""Agent Framework Adoption Growth Chart

Visualizes agent framework adoption using GitHub star growth trajectories,
AI coding tool market share, and key adoption milestones as proxy indicators
for MCP SDK download trends (time-series data unavailable).

Sources: GitHub framework stats, LangChain 2025 survey, JetBrains 2025,
         Stack Overflow 2025, DX DevCycle Q4 2025.
"""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent))

import matplotlib
matplotlib.use("Agg")

# Patch matplotlib Path.__deepcopy__ to break Python 3.14 recursion loop
try:
    from matplotlib.path import Path as MPLPath
    _orig = MPLPath.__deepcopy__
    def _safe_deepcopy(self, memo):
        if id(self) in memo:
            return memo[id(self)]
        memo[id(self)] = self
        return self
    MPLPath.__deepcopy__ = _safe_deepcopy
except Exception:
    pass

import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import numpy as np
import os

from src.data.agent_adoption import (
    github_framework_stats,
    agent_survey_data,
    developer_ai_adoption,
)
from src.utils.styling import (
    get_theme,
    EXPORT_DPI,
    AGENT_GROWTH,
    PRODUCTIVITY,
    GRAY_DARK,
    GRAY_MEDIUM,
    GRAY_LIGHT,
    WHITE,
    WARNING_ZONE,
    BUBBLE_ZONE,
)


# ---------------------------------------------------------------------------
# Approximate GitHub star growth trajectories (thousands)
# These are illustrative estimates based on known framework launch dates
# and growth patterns — exact time-series data was unavailable.
# ---------------------------------------------------------------------------

_framework_stars = {
    # (year, month_frac): stars_in_thousands
    "CrewAI": {
        2023.5:  2,
        2023.75: 5,
        2024.0:  10,
        2024.25: 15,
        2024.5:  20,
        2024.75: 25,
        2025.0:  30,
        2025.25: 36,
        2025.5:  42,
        2025.75: 48,
        2026.0:  55,
    },
    "LangGraph": {
        2023.5:  1,
        2023.75: 4,
        2024.0:  9,
        2024.25: 16,
        2024.5:  24,
        2024.75: 32,
        2025.0:  42,
        2025.25: 52,
        2025.5:  62,
        2025.75: 72,
        2026.0:  84,
    },
    "AutoGen": {
        2023.25: 2,
        2023.5:  5,
        2023.75: 10,
        2024.0:  18,
        2024.25: 28,
        2024.5:  38,
        2024.75: 48,
        2025.0:  58,
        2025.25: 68,
        2025.5:  78,
        2025.75: 88,
        2026.0: 100,
    },
}

_framework_colors = {
    "CrewAI":    "#e74c3c",   # Red
    "LangGraph": "#3498db",   # Blue
    "AutoGen":   "#2ecc71",   # Green
}

# ---------------------------------------------------------------------------
# Market share of AI coding tools
# ---------------------------------------------------------------------------

_market_share = [
    {"tool": "GitHub Copilot", "share": 42, "color": "#00a4ef"},
    {"tool": "Cursor",          "share": 18, "color": "#f59e0b"},
    {"tool": "Amazon Q",        "share": 11, "color": "#ff9900"},
    {"tool": "Replit AI",       "share": 12, "color": "#f24e1e"},
    {"tool": "Tabnine",         "share":  8, "color": "#8b5cf6"},
    {"tool": "Others",          "share":  9, "color": "#95a5a6"},
]

# ---------------------------------------------------------------------------
# Adoption milestones
# ---------------------------------------------------------------------------

_milestones = [
    {"year": 2023.25, "label": "AutoGen\nlaunch", "y": 105},
    {"year": 2023.50, "label": "CrewAI\nlaunch", "y": 100},
    {"year": 2023.50, "label": "LangGraph\nlaunch", "y": 95},
    {"year": 2024.83, "label": "MCP SDK\nlaunch", "y": 90},
    {"year": 2025.10, "label": "57.3% production\nadoption\n(LangChain)", "y": 85},
    {"year": 2025.50, "label": "20M Copilot\nusers", "y": 80},
]


def plot_mcp_downloads() -> str:
    """Generate the agent framework adoption growth chart.

    Combined visualization with two subplots:
      1. GitHub star growth trajectories for top agent frameworks
      2. Horizontal bar chart of AI coding tool market share
    Plus adoption milestones overlaid on the growth chart.
    """
    plt.rcParams.update(get_theme())

    fig = plt.figure(figsize=(14, 9), facecolor=WHITE)

    # Create a 2-row grid with unequal heights
    gs = fig.add_gridspec(2, 1, height_ratios=[1, 0.55], hspace=0.35)

    # ========================================================================
    # Panel 1: GitHub star growth trajectories
    # ========================================================================
    ax1 = fig.add_subplot(gs[0])
    ax1.set_facecolor("#fafafa")
    ax1.spines["top"].set_visible(False)
    ax1.spines["right"].set_visible(False)
    ax1.spines["left"].set_color("#cccccc")
    ax1.spines["bottom"].set_color("#cccccc")

    # Plot each framework
    for name, stars in _framework_stars.items():
        xs = sorted(stars.keys())
        ys = [stars[x] for x in xs]
        ax1.plot(xs, ys, color=_framework_colors[name], linewidth=2.5,
                 marker="o", markersize=4, label=name, zorder=5)

    # Milestones
    ax1.axvspan(2024.7, 2025.0, alpha=0.06, color=AGENT_GROWTH, zorder=2)
    ax1.text(2024.85, 108, "MCP Era", fontsize=9,
             color=AGENT_GROWTH, fontweight="bold", ha="center")

    for m in _milestones:
        ax1.plot(m["year"], m["y"], "v", color=WARNING_ZONE,
                 markersize=8, zorder=6, clip_on=False)
        ax1.annotate(m["label"],
                     xy=(m["year"], m["y"]),
                     xytext=(m["year"], m["y"] - 12),
                     fontsize=7.5, ha="center", color=GRAY_DARK,
                     fontweight="bold", clip_on=False)

    ax1.set_title("Agent Framework Adoption Growth",
                   fontsize=17, fontweight="bold", pad=12)
    ax1.set_xlabel("Year", fontsize=11)
    ax1.set_ylabel("GitHub Stars (thousands)", fontsize=11)
    ax1.legend(loc="upper left", fontsize=9.5, framealpha=0.9)
    ax1.grid(True, alpha=0.3, axis="y")
    ax1.set_ylim(0, 115)
    ax1.set_xlim(2023.0, 2026.3)
    ax1.xaxis.set_major_locator(mticker.MultipleLocator(0.5))
    ax1.xaxis.set_major_formatter(
        mticker.FuncFormatter(lambda v, p: f"{int(v)}\nQ{int((v % 1)*4) or 4}"))
    ax1.yaxis.set_major_locator(mticker.MultipleLocator(20))

    # ========================================================================
    # Panel 2: AI coding tool market share
    # ========================================================================
    ax2 = fig.add_subplot(gs[1])
    ax2.set_facecolor("#fafafa")
    ax2.spines["top"].set_visible(False)
    ax2.spines["right"].set_visible(False)
    ax2.spines["left"].set_visible(False)
    ax2.spines["bottom"].set_color("#cccccc")

    tools = [s["tool"] for s in _market_share]
    shares = [s["share"] for s in _market_share]
    colors = [s["color"] for s in _market_share]

    y_pos = np.arange(len(tools))
    bars = ax2.barh(y_pos, shares, color=colors, height=0.6,
                     edgecolor="white", linewidth=0.5)

    # Value labels
    for bar, share in zip(bars, shares):
        ax2.text(bar.get_width() + 0.5, bar.get_y() + bar.get_height() / 2,
                 f"{share}%", va="center", fontsize=10,
                 fontweight="bold", color=GRAY_DARK)

    ax2.set_yticks(y_pos)
    ax2.set_yticklabels(tools, fontsize=10)
    ax2.set_xlabel("Market Share (%)", fontsize=10)
    ax2.set_xlim(0, 55)
    ax2.set_title("AI Coding Tools — Paid Market Share",
                   fontsize=13, fontweight="bold", pad=8)
    ax2.grid(False)

    # ========================================================================
    # Subtitle across the figure
    # ========================================================================
    fig.text(0.5, 0.02,
             "GitHub stars and market share — the infrastructure layer of agentic AI\n"
             "Note: Framework star counts are approximate estimates; MCP SDK download "
             "time-series data unavailable. Market share: DX DevCycle 2025.",
             fontsize=9, ha="center", color=GRAY_MEDIUM,
             transform=fig.transFigure)

    # Save
    path = os.path.join("output/charts", "09_mcp_downloads.png")
    os.makedirs(os.path.dirname(path), exist_ok=True)
    fig.savefig(path, dpi=EXPORT_DPI,
                facecolor=fig.get_facecolor(), edgecolor="none",
                bbox_inches="tight")
    plt.close(fig)
    return path


def main():
    path = plot_mcp_downloads()
    print(f"Chart saved: {path}")


if __name__ == "__main__":
    main()
