# =============================================================================
# Indicator Makefile
# Indicator: PineScript authoring + data + browser.
# =============================================================================

.PHONY: help \
	install install-deps install-playwright install-tvdatafeed uninstall reinstall \
	agent-import agent-uninstall uninstall-all env-active env-deactive status version doctor \
	post-install-check \
	ohlcv search rating screener model-status model-setup model-forecast \
	vector-status vector-setup vector-drop cache-status cache-flush cache-cleanup \
	login session-check push screenshot \
	pine-new pine-list pine-validate pine-show \
	mcp mcp-data mcp-browser mcp-agent mcp-config-claude mcp-config-pi \
	lint fmt test \
	tree clean clean-temp clean-screenshots clean-sessions clean-all

.DEFAULT_GOAL := help

# =============================================================================
# Configuration
# =============================================================================
CONDA_ENV       ?= indicator
PYTHON_VERSION  ?= 3.11
PLATFORM        ?= auto
FORCE_INSTALL   ?= 0
SCRIPTS_DIR     := scripts
SCREENSHOTS_DIR := screenshots
INDICATOR_MINIFORGE_DIR ?= $(HOME)/.indicator/miniforge3
export PATH := $(INDICATOR_MINIFORGE_DIR)/bin:$(HOME)/miniforge3/bin:$(HOME)/miniconda3/bin:/opt/homebrew/Caskroom/miniforge/base/bin:/usr/local/Caskroom/miniforge/base/bin:$(PATH)

# Run a command inside the conda env without requiring the user to activate.
# `--live-stream` + `--no-capture-output` keeps stdout/stderr flowing in real time.
RUN := env PYTHONPATH="$(CURDIR)/src" conda run -n $(CONDA_ENV) --live-stream --no-capture-output
TV_CLI := python -m indicator.cli.main

# Platform detection (parity with skin_type_regonize_model)
IS_MAC := $(shell [ "$$(uname -s)" = "Darwin" ] && echo 1 || echo 0)

# =============================================================================
# Help
# =============================================================================
help:
	@echo "Indicator — PineScript authoring + data + browser automation"
	@echo ""
	@echo "GETTING STARTED"
	@echo "  make install              The one command. Idempotent. Run this every time."
	@echo "                            Handles fresh install, upgrades, and re-runs of the wizard."
	@echo "  make uninstall-all        Full uninstall — removes everything cleanly"
	@echo "  make status               Show TradingView config + auth status"
	@echo "  make doctor               Diagnose env / deps / cookies / skills"
	@echo "  make post-install-check   Verify packages, CLIs, Redis, pgvector, and features"
	@echo ""
	@echo "ENVIRONMENT (power-user)"
	@echo "  make install FORCE_INSTALL=1   Re-run core install even if binaries are already in place"
	@echo "  make install-deps              (re)install Python deps only"
	@echo "  make install-playwright        Download Chromium for Playwright"
	@echo "  make install-tvdatafeed        Re-pin tvdatafeed from GitHub"
	@echo "  make reinstall                 uninstall + install"
	@echo "  make uninstall                 Remove conda env '$(CONDA_ENV)' only"
	@echo "  make agent-import [PLATFORM=auto]  Re-import a specific agent's MCP/skills"
	@echo "  make agent-uninstall [PLATFORM=auto|all|...]  Remove TradingView MCP from selected agent(s)"
	@echo "  make env-active                Print: 'source conda-env-active.sh $(CONDA_ENV)'"
	@echo "  make env-deactive              Print: 'source conda-env-deactive.sh $(CONDA_ENV)'"
	@echo ""
	@echo "AGENT SKILLS (multi-agent skill wiring)"
	@echo "  make install-skills       Wire skill into all agents (.claude, .pi, .cursor, AGENTS.md, GEMINI.md)"
	@echo "  make install-skills-global  Also symlink into ~/.claude/skills/ (user-global)"
	@echo "  make update-skills        Refresh autogen files (run after editing canonical skill)"
	@echo "  make check-skills         Report which discovery points are wired up"
	@echo "  make uninstall-skills     Remove managed symlinks + autogen files"
	@echo ""
	@echo "DATA (read TradingView)"
	@echo "  make ohlcv SYMBOL=NASDAQ:AAPL [INTERVAL=1D] [BARS=500]"
	@echo "  make search Q=tesla [LIMIT=20]"
	@echo "  make rating SYMBOL=NASDAQ:AAPL"
	@echo "  make screener [MARKET=america] [FILTER='RSI < 30'] [LIMIT=50]"
	@echo ""
	@echo "MODEL FORECAST (server-side API; stock/ETF/index only)"
	@echo "  make model-status                            Show forecast API configuration/status"
	@echo "  make model-setup                             Validate forecast API configuration"
	@echo "  make model-forecast SYMBOL=NASDAQ:TSLA       Fetch 20d forecast from API"
	@echo "  make model-forecast SYMBOL=TSLA REFRESH=1    Ask API to refresh/recompute first"
	@echo ""
	@echo "NEWS VECTOR DATABASE (PostgreSQL + pgvector)"
	@echo "  make vector-status                           Check pgvector extension/news table status"
	@echo "  make vector-setup                            Enable extension + safely merge news vector table/indexes"
	@echo "  make vector-drop                             Drop Indicator-owned news vector table"
	@echo "  make vector-setup                            Uses vector.dim from config/indicator.yaml"
	@echo ""
	@echo "REDIS TEMP CACHE"
	@echo "  make cache-status                            Check Redis price/news/analysis cache"
	@echo "  make cache-flush                             Delete Indicator-owned Redis cache keys"
	@echo "  make cache-cleanup                           Delete local temp analysis artifacts older than 24h"
	@echo ""
	@echo "BROWSER (write to TradingView)"
	@echo "  make login                Interactive login (visible browser)"
	@echo "  make session-check        Verify cookie / profile still valid"
	@echo "  make push SCRIPT=scripts/indicators/foo.pine [APPLY=NASDAQ:AAPL] [SHOT=1]"
	@echo "  make screenshot [SYMBOL=NASDAQ:AAPL] [OUT=path.png]"
	@echo ""
	@echo "PINE SCRIPT (local authoring)"
	@echo "  make pine-new KIND=indicator|strategy|webhook NAME=my_rsi"
	@echo "  make pine-list            List all .pine files"
	@echo "  make pine-validate SCRIPT=scripts/indicators/foo.pine"
	@echo "  make pine-show SCRIPT=scripts/indicators/foo.pine"
	@echo ""
	@echo "MCP SERVERS (agents)"
	@echo "  make mcp                  Run the Indicator MCP server in the foreground"
	@echo "  make mcp-data             Run the legacy split data MCP server"
	@echo "  make mcp-browser          Run the legacy split browser MCP server"
	@echo "  make mcp-agent            Run the legacy split agent MCP server"
	@echo "  make mcp-config-claude    Print JSON snippet for Claude Desktop"
	@echo "  make mcp-config-pi        Print TOML snippet for pi"
	@echo ""
	@echo "QUALITY"
	@echo "  make lint                 ruff check src/"
	@echo "  make fmt                  ruff format src/"
	@echo "  make test                 pytest"
	@echo ""
	@echo "HOUSEKEEPING"
	@echo "  make tree                 Show project tree"
	@echo "  make clean                Remove __pycache__ / *.pyc"
	@echo "  make clean-temp           Remove temp analysis artifacts older than 24h"
	@echo "  make clean-screenshots    Remove generated PNGs"
	@echo "  make clean-sessions       Remove saved browser profiles (forces re-login)"
	@echo "  make clean-all            All of the above"

# =============================================================================
# Environment setup
# =============================================================================
install:
	@echo "[1/5] Checking core install for conda env '$(CONDA_ENV)' (python=$(PYTHON_VERSION))..."
	@bash -c '\
		set -eo pipefail; \
		if [[ "$(FORCE_INSTALL)" != "1" ]] \
		   && command -v conda >/dev/null 2>&1 \
		   && conda env list | sed "s/[[:space:]].*//" | grep -qx "$(CONDA_ENV)" \
		   && conda run -n "$(CONDA_ENV)" python -c "import importlib.metadata as md; md.version('indicator'); import indicator,mcp,playwright,tradingview_screener,psycopg,pgvector,yaml,redis; import indicator.mcp.indicator_server,indicator.mcp.data_server,indicator.mcp.browser_server,indicator.mcp.agent_server" >/dev/null 2>&1 \
		   && conda run -n "$(CONDA_ENV)" sh -lc "command -v trading-view >/dev/null && command -v indicator >/dev/null && command -v indicator-mcp >/dev/null && command -v trading-view-mcp-data >/dev/null && command -v trading-view-mcp-browser >/dev/null && command -v trading-view-mcp-agent >/dev/null" >/dev/null 2>&1 \
		   && conda run -n "$(CONDA_ENV)" trading-view --help >/dev/null 2>&1; then \
			echo "  core already installed ✓ (use FORCE_INSTALL=1 to reinstall)"; \
		else \
			export TV_PYTHON_VERSION=$(PYTHON_VERSION); \
			source ./conda-env-active.sh $(CONDA_ENV); \
		fi \
	'
	@echo ""
	@echo "[2/5] Verifying TradingView CLI + model API client..."
	-@./tools/progress.sh --success "TradingView CLI available ✓" --failure "TradingView CLI NOT available ✗" "Checking TradingView CLI" -- $(RUN) $(TV_CLI) --help
	-@./tools/progress.sh --success "Model API client available ✓" --failure "Model API client NOT available ✗" "Checking model API client" -- $(RUN) $(TV_CLI) model --help
	-@./tools/progress.sh --success "News vector client available ✓" --failure "News vector client NOT available ✗" "Checking news vector client" -- $(RUN) $(TV_CLI) vector --help
	-@./tools/progress.sh --success "Redis cache client available ✓" --failure "Redis cache client NOT available ✗" "Checking Redis cache client" -- $(RUN) $(TV_CLI) cache --help
	@mkdir -p temp && echo "  Analysis artifact dir ready ✓ (temp/)"
	-@$(RUN) $(TV_CLI) cache cleanup 2>/dev/null || true
	@echo ""
	@echo "[3/5] Interactive TradingView + agent/MCP setup..."
	@echo "  Progress indicators show background work; prompts may wait for your input."
	@CONDA_ENV="$(CONDA_ENV)" PLATFORM="$(PLATFORM)" ./tools/interactive_install.sh
	@echo ""
	@echo "[4/5] Done. Useful checks:"
	@echo "  make status"
	@echo "  make session-check"
	@echo "  make model-status"
	@echo "  make model-setup                              # verify model API config"
	@echo "  make model-forecast SYMBOL=NASDAQ:TSLA MODEL_JSON=1"
	@echo "  make vector-status                           # verify news vector DB env"
	@echo "  make vector-setup                            # initialize/merge after setting DATABASE_URL"
	@echo "  make cache-status                            # verify Redis temp cache"
	@echo "  make cache-cleanup                           # prune local temp artifacts older than 24h"
	@echo "  make doctor"
	@echo "  make check-skills"
	@echo ""
	@echo "Final TradingView login status:"
	-@$(RUN) $(TV_CLI) browser session-check 2>/dev/null || echo "  TradingView login status check failed — retry with 'make session-check'"
	@echo ""
	@echo "Final model forecast API status:"
	-@$(RUN) $(TV_CLI) model status || echo "  Model status check failed — retry with 'make model-status'"
	@echo ""
	@echo "Final news vector DB status:"
	-@$(RUN) $(TV_CLI) vector status 2>/dev/null || echo "  News vector DB not configured — set DATABASE_URL and run 'make vector-setup'"
	@echo ""
	@echo "Final Redis cache status:"
	-@$(RUN) $(TV_CLI) cache status 2>/dev/null || echo "  Redis cache not configured — set REDIS_URL and run 'make cache-status'"
	@echo ""
	@echo "[5/5] Post-install feature check..."
	@$(MAKE) post-install-check

install-deps:
	$(RUN) python -m pip install --upgrade pip
	$(RUN) python -m pip install -e ".[data,dev]"

install-playwright:
	$(RUN) python -m playwright install chromium

install-tvdatafeed:
	$(RUN) python -m pip install --upgrade --force-reinstall \
		git+https://github.com/rongardF/tvdatafeed.git

uninstall:
	@bash -c 'source ./conda-env-deactive.sh $(CONDA_ENV)'

reinstall:
	$(MAKE) uninstall
	$(MAKE) install

env-active:
	@echo "Run this in your shell (don't run it through make):"
	@echo ""
	@echo "  source conda-env-active.sh $(CONDA_ENV)"
	@echo ""

env-deactive:
	@echo "Run this in your shell (don't run it through make):"
	@echo ""
	@echo "  source conda-env-deactive.sh $(CONDA_ENV)"
	@echo ""

status:
	$(RUN) $(TV_CLI) status

version:
	$(RUN) $(TV_CLI) version

agent-import:
	@./tools/import_agent_tools.sh --platform "$(PLATFORM)"

agent-uninstall:
	@./tools/uninstall_agent_tools.sh --platform "$(PLATFORM)"

doctor:
	@echo "─── Agent skills ───────────────────────────────────────"
	@./tools/install_skills.sh --check 2>&1 | tail -n +4 || echo "  (run 'make install-skills' to wire up agent discovery)"
	@echo ""
	@echo "─── Conda ──────────────────────────────────────────────"
	@command -v conda >/dev/null && echo "  conda ✓ ($$(conda --version))" || echo "  conda ✗ — run 'make install' to auto-install Miniforge"
	@conda env list | awk '{print $$1}' | grep -qx "$(CONDA_ENV)" \
		&& echo "  env '$(CONDA_ENV)' ✓" \
		|| echo "  env '$(CONDA_ENV)' ✗ — run 'make install'"
	@echo ""
	@echo "─── Package ────────────────────────────────────────────"
	-@$(RUN) python -c "import indicator; print('  indicator ✓', indicator.__file__ if hasattr(indicator,'__file__') else '')" 2>/dev/null || echo "  indicator ✗ — run 'make install-deps'"
	-@$(RUN) python -c "import importlib.util,sys; sys.exit(0 if importlib.util.find_spec('tvDatafeed') or importlib.util.find_spec('tvdatafeed') else 1)" 2>/dev/null && echo "  tvdatafeed   ✓" || echo "  tvdatafeed   ✗ — run 'make install-tvdatafeed'"
	-@$(RUN) python -c "import playwright" 2>/dev/null && echo "  playwright   ✓" || echo "  playwright   ✗ — run 'make install-deps'"
	-@$(RUN) python -c "import tradingview_screener" 2>/dev/null && echo "  screener     ✓" || echo "  screener     ✗"
	-@$(RUN) python -c "import psycopg, pgvector" 2>/dev/null && echo "  pgvector     ✓" || echo "  pgvector     ✗ — run 'make install-deps'"
	-@$(RUN) python -c "import redis" 2>/dev/null && echo "  redis        ✓" || echo "  redis        ✗ — run 'make install-deps'"
	-@$(RUN) python -c "import yaml" 2>/dev/null && echo "  yaml         ✓" || echo "  yaml         ✗ — run 'make install-deps'"
	-@$(RUN) python -c "import mcp" 2>/dev/null && echo "  mcp          ✓" || echo "  mcp          ✗"
	@echo ""
	@echo "─── Model forecast API ─────────────────────────────────"
	-@$(RUN) $(TV_CLI) model status 2>/dev/null || echo "  model API ✗ — set model.api_url in config/indicator.yaml"
	@echo ""
	@echo "─── News vector DB ──────────────────────────────────────"
	-@$(RUN) $(TV_CLI) vector status 2>/dev/null || echo "  news vector DB ✗ — set DATABASE_URL and run 'make vector-setup'"
	@echo ""
	@echo "─── Redis temp cache ────────────────────────────────────"
	-@$(RUN) $(TV_CLI) cache status 2>/dev/null || echo "  Redis cache ✗ — set REDIS_URL and run 'make cache-status'"
	@echo ""
	@echo "─── Config ─────────────────────────────────────────────"
	@[ -f .env ] && echo "  .env file    ✓" || echo "  .env file    ✗ — run 'cp .env.example .env'"
	-@$(RUN) $(TV_CLI) status 2>/dev/null || true

post-install-check:
	$(RUN) $(TV_CLI) post-install-check \
		$(if $(filter 1 true yes,$(CHECK_JSON)),--json,) \
		$(if $(filter 1 true yes,$(CHECK_STRICT_OPTIONAL)),--strict-optional,)

# =============================================================================
# Agent skill installation
# =============================================================================
install-skills:
	@./tools/install_skills.sh

update-skills: install-skills

install-skills-global:
	@TV_INSTALL_GLOBAL_CLAUDE=1 ./tools/install_skills.sh

check-skills:
	@./tools/install_skills.sh --check

uninstall-skills:
	@./tools/install_skills.sh --uninstall

# =============================================================================
# Data (read)
# =============================================================================
SYMBOL   ?= NASDAQ:AAPL
INTERVAL ?= 1D
BARS     ?= 500
Q        ?=
LIMIT    ?= 20
MARKET   ?= america
FILTER   ?=
MODEL_REPO ?=
MODEL_CSV ?=
MODEL_CONDA_ENV ?=
MODEL_PERIOD ?= 10y
MODEL_API_URL ?=
MODEL_STATUS_URL ?=
VECTOR_DB_URL ?=
VECTOR_SCHEMA ?=
VECTOR_TABLE ?=
VECTOR_DIM ?=
VECTOR_JSON ?= 0
VECTOR_DROP_SCHEMA ?= 1
VECTOR_CLEANUP ?= 1
CACHE_JSON ?= 0
CACHE_KIND ?=
CACHE_RETENTION_HOURS ?=
CACHE_DRY_RUN ?= 0
CACHE_CLEANUP ?= 1
CHECK_JSON ?= 0
CHECK_STRICT_OPTIONAL ?= 0
REFRESH ?= 0
MODEL_JSON ?= 0

ohlcv:
	@[ -n "$(SYMBOL)" ] || (echo "ERROR: SYMBOL is required, e.g. make ohlcv SYMBOL=NASDAQ:AAPL"; exit 1)
	$(RUN) $(TV_CLI) data ohlcv "$(SYMBOL)" --interval $(INTERVAL) --bars $(BARS)

search:
	@[ -n "$(Q)" ] || (echo "ERROR: Q is required, e.g. make search Q=tesla"; exit 1)
	$(RUN) $(TV_CLI) data search "$(Q)" --limit $(LIMIT)

rating:
	@[ -n "$(SYMBOL)" ] || (echo "ERROR: SYMBOL is required"; exit 1)
	$(RUN) $(TV_CLI) data rating "$(SYMBOL)" --interval $(INTERVAL)

screener:
	$(RUN) $(TV_CLI) data screener --market $(MARKET) --limit $(LIMIT) \
		$(if $(FILTER),--filter "$(FILTER)",)

model-status:
	$(RUN) $(TV_CLI) model status \
		$(if $(MODEL_REPO),--repo "$(MODEL_REPO)",) \
		$(if $(MODEL_CSV),--csv "$(MODEL_CSV)",) \
		$(if $(MODEL_CONDA_ENV),--conda-env "$(MODEL_CONDA_ENV)",) \
		$(if $(MODEL_API_URL),--api-url "$(MODEL_API_URL)",) \
		$(if $(MODEL_STATUS_URL),--status-url "$(MODEL_STATUS_URL)",) \
		$(if $(filter 1 true yes,$(MODEL_JSON)),--json,)

model-setup:
	$(RUN) $(TV_CLI) model setup \
		$(if $(MODEL_REPO),--repo "$(MODEL_REPO)",) \
		$(if $(MODEL_CONDA_ENV),--conda-env "$(MODEL_CONDA_ENV)",) \
		$(if $(MODEL_API_URL),--api-url "$(MODEL_API_URL)",) \
		$(if $(MODEL_STATUS_URL),--status-url "$(MODEL_STATUS_URL)",) \
		$(if $(filter 1 true yes,$(MODEL_JSON)),--json,)

model-forecast:
	@[ -n "$(SYMBOL)" ] || (echo "ERROR: SYMBOL is required, e.g. make model-forecast SYMBOL=NASDAQ:TSLA"; exit 1)
	$(RUN) $(TV_CLI) model forecast "$(SYMBOL)" \
		$(if $(filter 1 true yes,$(REFRESH)),--refresh,) \
		$(if $(MODEL_REPO),--repo "$(MODEL_REPO)",) \
		$(if $(MODEL_CSV),--csv "$(MODEL_CSV)",) \
		$(if $(MODEL_CONDA_ENV),--conda-env "$(MODEL_CONDA_ENV)",) \
		$(if $(MODEL_API_URL),--api-url "$(MODEL_API_URL)",) \
		--period "$(MODEL_PERIOD)" \
		$(if $(filter 1 true yes,$(MODEL_JSON)),--json,)

vector-status:
	$(RUN) $(TV_CLI) vector status \
		$(if $(VECTOR_DB_URL),--database-url "$(VECTOR_DB_URL)",) \
		$(if $(VECTOR_SCHEMA),--schema "$(VECTOR_SCHEMA)",) \
		$(if $(VECTOR_TABLE),--table "$(VECTOR_TABLE)",) \
		$(if $(filter 1 true yes,$(VECTOR_JSON)),--json,)

vector-setup:
	$(RUN) $(TV_CLI) vector setup \
		$(if $(VECTOR_DB_URL),--database-url "$(VECTOR_DB_URL)",) \
		$(if $(VECTOR_SCHEMA),--schema "$(VECTOR_SCHEMA)",) \
		$(if $(VECTOR_TABLE),--table "$(VECTOR_TABLE)",) \
		$(if $(VECTOR_DIM),--dim "$(VECTOR_DIM)",) \
		$(if $(filter 1 true yes,$(VECTOR_JSON)),--json,)

vector-drop:
	$(RUN) $(TV_CLI) vector drop \
		$(if $(VECTOR_DB_URL),--database-url "$(VECTOR_DB_URL)",) \
		$(if $(VECTOR_SCHEMA),--schema "$(VECTOR_SCHEMA)",) \
		$(if $(VECTOR_TABLE),--table "$(VECTOR_TABLE)",) \
		--yes \
		$(if $(filter 0 false no,$(VECTOR_DROP_SCHEMA)),--keep-schema,) \
		$(if $(filter 1 true yes,$(VECTOR_JSON)),--json,)

cache-status:
	$(RUN) $(TV_CLI) cache status \
		$(if $(filter 1 true yes,$(CACHE_JSON)),--json,)

cache-flush:
	$(RUN) $(TV_CLI) cache flush \
		--yes \
		$(if $(CACHE_KIND),--kind "$(CACHE_KIND)",) \
		$(if $(filter 1 true yes,$(CACHE_JSON)),--json,)

cache-cleanup:
	$(RUN) $(TV_CLI) cache cleanup \
		$(if $(CACHE_RETENTION_HOURS),--older-than-hours "$(CACHE_RETENTION_HOURS)",) \
		$(if $(filter 1 true yes,$(CACHE_DRY_RUN)),--dry-run,) \
		$(if $(filter 1 true yes,$(CACHE_JSON)),--json,)

# =============================================================================
# Browser (write)
# =============================================================================
SCRIPT  ?=
SHOT    ?= 0
OUT     ?=
LAYOUT  ?=
APPLY   ?=

login:
	$(RUN) $(TV_CLI) browser login

session-check:
	$(RUN) $(TV_CLI) browser session-check

push:
	@[ -n "$(SCRIPT)" ] || (echo "ERROR: SCRIPT is required, e.g. make push SCRIPT=scripts/indicators/foo.pine APPLY=NASDAQ:AAPL"; exit 1)
	$(RUN) $(TV_CLI) browser push "$(SCRIPT)" \
		$(if $(APPLY),--apply "$(APPLY)",) \
		$(if $(filter 1 true yes,$(SHOT)),--screenshot,)

screenshot:
	$(RUN) $(TV_CLI) browser screenshot \
		$(if $(SYMBOL),--symbol "$(SYMBOL)",) \
		$(if $(LAYOUT),--layout "$(LAYOUT)",) \
		$(if $(OUT),--out "$(OUT)",)

# =============================================================================
# Pine (local)
# =============================================================================
KIND ?= indicator
NAME ?=

pine-new:
	@[ -n "$(NAME)" ] || (echo "ERROR: NAME is required, e.g. make pine-new KIND=indicator NAME=my_rsi"; exit 1)
	$(RUN) $(TV_CLI) pine new $(KIND) $(NAME)

pine-list:
	$(RUN) $(TV_CLI) pine list

pine-validate:
	@[ -n "$(SCRIPT)" ] || (echo "ERROR: SCRIPT is required"; exit 1)
	$(RUN) $(TV_CLI) pine validate "$(SCRIPT)"

pine-show:
	@[ -n "$(SCRIPT)" ] || (echo "ERROR: SCRIPT is required"; exit 1)
	$(RUN) $(TV_CLI) pine show "$(SCRIPT)"

# =============================================================================
# MCP servers
# =============================================================================
mcp:
	@echo "Starting Indicator MCP server on stdio. Ctrl-C to stop."
	$(RUN) python -m indicator.mcp.indicator_server

mcp-data:
	@echo "Starting legacy split data MCP server on stdio. Ctrl-C to stop."
	$(RUN) python -m indicator.mcp.data_server

mcp-browser:
	@echo "Starting legacy split browser MCP server on stdio. Ctrl-C to stop."
	$(RUN) python -m indicator.mcp.browser_server

mcp-agent:
	@echo "Starting legacy split agent MCP server on stdio. Ctrl-C to stop."
	$(RUN) python -m indicator.mcp.agent_server

mcp-config-claude:
	@echo "Paste this into ~/Library/Application Support/Claude/claude_desktop_config.json:"
	@echo ""
	@echo '{'
	@echo '  "mcpServers": {'
	@echo '    "indicator": {'
	@echo "      \"command\": \"$$(conda run -n $(CONDA_ENV) which indicator-mcp 2>/dev/null || echo 'indicator-mcp')\","
	@echo '      "env": { "TV_SESSIONID": "<paste-here>" }'
	@echo '    }'
	@echo '  }'
	@echo '}'

mcp-config-pi:
	@echo "Paste this into .pi/config.toml (or your global pi config):"
	@echo ""
	@echo '[mcp_servers.indicator]'
	@echo "command = \"$$(conda run -n $(CONDA_ENV) which indicator-mcp 2>/dev/null || echo 'indicator-mcp')\""
	@echo 'env = { TV_SESSIONID = "<paste-here>" }'

# =============================================================================
# Quality
# =============================================================================
lint:
	$(RUN) ruff check src/

fmt:
	$(RUN) ruff format src/

test:
	$(RUN) pytest -q

# =============================================================================
# Housekeeping
# =============================================================================
tree:
	@command -v tree >/dev/null && tree -I '__pycache__|*.egg-info|.venv|venv|sessions|.git' -L 4 . \
		|| find . -type f -not -path '*/\.*' -not -path '*/__pycache__/*' -not -path '*/sessions/*' | sort | head -60

clean:
	@find . -type d -name __pycache__ -prune -exec rm -rf {} + 2>/dev/null || true
	@find . -type f -name '*.pyc' -delete 2>/dev/null || true
	@find . -type d -name '*.egg-info' -prune -exec rm -rf {} + 2>/dev/null || true
	@echo "Cleaned pyc / egg-info."

clean-screenshots:
	@find $(SCREENSHOTS_DIR) -type f ! -name '.gitkeep' -delete 2>/dev/null || true
	@echo "Cleaned $(SCREENSHOTS_DIR)/"

clean-sessions:
	@rm -rf tools/tv_browser/sessions/* 2>/dev/null || true
	@echo "Cleaned browser profiles (you'll need to log in again)."

clean-temp: cache-cleanup

clean-all: clean clean-temp clean-screenshots clean-sessions
	@echo "All clean."

# =============================================================================
# Full uninstall — removes Indicator from every agent + the conda env +
# generated/runtime artifacts. Repo source files stay; re-run 'make install'
# anytime to reinstall.
#
# Optional flag: KEEP_ENV=1 — preserve .env (otherwise it's deleted, since it
# may contain TradingView cookies / API keys you no longer want lying around).
# =============================================================================
KEEP_ENV ?= 0

uninstall-all:
	@echo "[1/8] Removing per-agent MCP registrations (Pi, Claude Desktop, Claude Code, Codex, Gemini, Cursor)..."
	@./tools/uninstall_agent_tools.sh --platform all || true
	@echo ""
	@echo "[2/8] Removing managed skill symlinks and generated context files (CLAUDE.md, AGENTS.md, GEMINI.md, .pi/APPEND_SYSTEM.md, .cursor/rules/*.mdc, docs/agent-skill-directory.md)..."
	@./tools/install_skills.sh --uninstall || true
	@echo ""
	@echo "[3/8] Removing project-local agent artifacts (.mcp.json, .cursor/mcp.json, .pi/{config.toml,settings.json,.indicator-auto-imported})..."
	@rm -f .mcp.json .cursor/mcp.json 2>/dev/null || true
	@rm -f .pi/.indicator-auto-imported .pi/.tv""-indicator-auto-imported 2>/dev/null || true
	@if [ -d .pi ]; then \
		[ -f .pi/config.toml ] && [ ! -s .pi/config.toml ] && rm -f .pi/config.toml || true; \
		[ -f .pi/settings.json ] && [ "$$(wc -c < .pi/settings.json | tr -d ' ')" -lt 5 ] && rm -f .pi/settings.json || true; \
		rmdir .pi/skills 2>/dev/null || true; \
		rmdir .pi/agent/skills 2>/dev/null || true; \
		rmdir .pi/agent 2>/dev/null || true; \
		rmdir .pi 2>/dev/null || true; \
	fi
	@if [ -d .cursor ]; then \
		rmdir .cursor/rules 2>/dev/null || true; \
		rmdir .cursor 2>/dev/null || true; \
	fi
	@if [ -d .claude/skills ]; then \
		rmdir .claude/skills 2>/dev/null || true; \
		rmdir .claude 2>/dev/null || true; \
	fi
	@echo ""
	@echo "[4/8] Removing browser session profile + screenshots..."
	@$(MAKE) -s clean-sessions || true
	@$(MAKE) -s clean-screenshots || true
	@echo ""
	@echo "[5/8] Removing PostgreSQL news vector DB (if DATABASE_URL is configured)..."
	@if [ "$(VECTOR_CLEANUP)" = "0" ]; then \
		echo "  Skipped news vector DB cleanup (VECTOR_CLEANUP=0)"; \
	else \
		$(RUN) $(TV_CLI) vector drop \
			$(if $(VECTOR_DB_URL),--database-url "$(VECTOR_DB_URL)",) \
			$(if $(VECTOR_SCHEMA),--schema "$(VECTOR_SCHEMA)",) \
			$(if $(VECTOR_TABLE),--table "$(VECTOR_TABLE)",) \
			--yes \
			$(if $(filter 0 false no,$(VECTOR_DROP_SCHEMA)),--keep-schema,) \
		|| echo "  News vector DB cleanup skipped or failed — set DATABASE_URL and retry 'make vector-drop' if needed"; \
	fi
	@echo ""
	@echo "[6/8] Flushing Redis temporary cache (if REDIS_URL is configured)..."
	@if [ "$(CACHE_CLEANUP)" = "0" ]; then \
		echo "  Skipped Redis cache cleanup (CACHE_CLEANUP=0)"; \
	else \
		$(RUN) $(TV_CLI) cache flush --yes \
			$(if $(CACHE_KIND),--kind "$(CACHE_KIND)",) \
		|| echo "  Redis cache cleanup skipped or failed — set REDIS_URL and retry 'make cache-flush' if needed"; \
	fi
	@echo ""
	@echo "[7/8] Removing stray *.bak files left from earlier sed passes..."
	@find . -type f -name '*.bak' -not -path '*/.git/*' -delete 2>/dev/null || true
	@echo ""
	@echo "[8/8] Removing conda env '$(CONDA_ENV)'..."
	@conda env list | awk '{print $$1}' | grep -qx "$(CONDA_ENV)" \
		&& conda env remove -y -n $(CONDA_ENV) \
		|| echo "  conda env '$(CONDA_ENV)' not present, skipping"
	@echo ""
	@if [ "$(KEEP_ENV)" = "1" ]; then \
		echo "  Kept .env (KEEP_ENV=1)"; \
	elif [ -f .env ]; then \
		rm -f .env && echo "  Removed .env (pass KEEP_ENV=1 to preserve cookies/keys)"; \
	fi
	@echo ""
	@echo "Done. Repo source files remain — run 'make install' to reinstall."
	@echo "If you want a fully clean slate, you can now also: rm -rf $(CURDIR)"
