#!/usr/bin/env python3
"""Check that Pine Script files don't exceed the 64 plot/plotchar call limit.

TradingView enforces a maximum of 64 plot() + plotchar() outputs per
indicator/strategy. Exceeding this causes silent truncation of data exports.

Exits 1 and prints the offending file + count if the limit is exceeded.
Usage: python3 tools/check_pine_plot_budget.py [file ...]
  Defaults to strategies/*.pine if no args given.
"""

import re
import sys
from glob import glob
from pathlib import Path

PLOT_LIMIT = 64
# TV counts plot/plotchar/plotshape/plotarrow/plotbar/plotcandle AND bgcolor()
# against the same 64-output limit.
PLOT_RE = re.compile(
    r"\bplot(?:char|shape|arrow|bar|candle)?\s*\(|\bbgcolor\s*\(",
    re.MULTILINE,
)


def count_plot_calls(path: str) -> int:
    text = Path(path).read_text(encoding="utf-8", errors="replace")
    # Strip line comments to avoid counting commented-out calls
    lines = []
    for line in text.splitlines():
        lines.append(re.sub(r"//.*", "", line))
    clean = "\n".join(lines)
    return len(PLOT_RE.findall(clean))


def main() -> int:
    targets = sys.argv[1:] or sorted(glob("strategies/*.pine"))
    if not targets:
        print("No Pine files found.", file=sys.stderr)
        return 0

    over_budget = False
    for path in targets:
        if not Path(path).is_file():
            continue
        count = count_plot_calls(path)
        if count > PLOT_LIMIT:
            print(f"❌  {path}")
            print(f"    {count} plot/plotchar calls — exceeds TV limit of {PLOT_LIMIT}")
            over_budget = True
        else:
            remaining = PLOT_LIMIT - count
            print(f"✅  {path}  ({count}/{PLOT_LIMIT} plots, {remaining} remaining)")

    if over_budget:
        print(f"\nFix: remove or combine plot() / plotchar() calls to stay within {PLOT_LIMIT}.")
        return 1

    return 0


if __name__ == "__main__":
    sys.exit(main())
