# docgen — code to diagram, and to everything else the IR can feed.
#
# Derived from where this file sits, so the folder can be copied anywhere and
# renamed and still work. The logic lives in the Python, never here.
#
#   make check                     prove it, on a tree it builds itself
#   make ir SRC=../station         extract -> out/ir.json
#   make graph                     out/ir.json -> out/graph.svg
#   make index                     out/ir.json -> out/index.md
#   make self                      run the whole pipeline over soleprint itself
#   make doctor                    what this machine has
#
# The pipeline is three commands and they compose, which is the point:
#
#   python3 -m docgen.extractors.python --root SRC -o ir.json
#   python3 -m docgen.ops ir.json --overview -o view.json
#   python3 -m docgen.emitters dot view.json -o graph.svg --theme dark

HERE   := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
PKG    := $(notdir $(HERE))
PARENT := $(patsubst %/,%,$(dir $(HERE)))
PY     ?= python3
RUN    := PYTHONPATH=$(PARENT) $(PY) -m

OUT    ?= $(HERE)/out
SRC    ?=
SCHEMA ?=
STYLE  ?= lucid
THEME  ?=
DEPTH  ?= 2
SCALE  ?= 0.55

THEME_ARG := $(if $(THEME),--theme $(THEME))

.PHONY: help check ir db code graph index site minimap explore docs view self doctor clean

help:  ## List every target
	@echo "docgen — static analysis of a tree, and the artifacts that fall out of it"
	@echo
	@grep -E '^[a-z-]+:.*?## .*$$' $(MAKEFILE_LIST) \
	  | awk 'BEGIN{FS=":.*?## "}{printf "  \033[1m%-10s\033[0m %s\n", $$1, $$2}'
	@echo
	@echo "  SRC=/path/to/tree     what to read           OUT=/path   where output goes"
	@echo "  SCHEMA=schema.json    a database instead     STYLE=lucid THEME=dark|lucid"
	@echo "  DEPTH=2               how deep to draw"

check:  ## Prove the pipeline, offline, needing nothing installed
	@$(PY) $(HERE)/selftest.py

ir:  ## Extract SRC into OUT/ir.json
	@test -n "$(SRC)" || { echo "Error: set SRC=/path/to/tree" >&2; exit 1; }
	@mkdir -p $(OUT)
	@$(RUN) $(PKG).extractors.python --root "$(SRC)" -o $(OUT)/ir.json
	@$(RUN) $(PKG).ir $(OUT)/ir.json

db:  ## Extract a graphgen-compatible SCHEMA into OUT/ir.json
	@test -n "$(SCHEMA)" || { echo "Error: set SCHEMA=/path/to/schema.json" >&2; exit 1; }
	@mkdir -p $(OUT)
	@$(RUN) $(PKG).extractors --schema "$(SCHEMA)" -o $(OUT)/ir.json
	@$(RUN) $(PKG).ir $(OUT)/ir.json

view:  ## OUT/ir.json -> OUT/view.json, the default view for its source type
	@$(RUN) $(PKG).ops $(OUT)/ir.json --overview -o $(OUT)/view.json

graph: view  ## OUT/view.json -> whatever its structure asks for
	@$(RUN) $(PKG).emitters auto $(OUT)/view.json -o $(OUT) \
	  --style $(STYLE) $(THEME_ARG)

site: view  ## OUT/view.json -> a self-contained docs site in OUT/site
	@$(RUN) $(PKG).emitters site $(OUT)/view.json -o $(OUT)/site \
	  --style $(STYLE) $(THEME_ARG)
	@echo "  open $(OUT)/site/index.html"

docs:  ## Regenerate the figures in docs/ — docgen documented by docgen
	@mkdir -p docs/img
	@$(RUN) $(PKG).extractors.python --root $(HERE) -o /tmp/$(PKG)-docs.json >/dev/null
	@$(RUN) $(PKG).ops /tmp/$(PKG)-docs.json --overview -o /tmp/$(PKG)-docs-view.json >/dev/null
	@$(RUN) $(PKG).emitters dot /tmp/$(PKG)-docs-view.json -o docs/img/architecture.svg -q
	@$(RUN) $(PKG).emitters minimap /tmp/$(PKG)-docs.json -o docs/img/minimap.svg --scale 0.5 --width 860
	@$(RUN) $(PKG).emitters erd $(OUT)/ir.json -o docs/img/erd.svg 2>/dev/null \
	  || echo "  (erd figure kept — needs a schema IR at $(OUT)/ir.json to refresh)"
	@PYTHONPATH=$(PARENT) $(PY) -c "from $(PKG).emitters.site import VIEWER, _slots, _fill; \
from $(PKG).style import Style; import pathlib; \
pathlib.Path('$(HERE)/docs/viewer.html').write_text( \
  _fill(VIEWER.replace('__TITLE__', 'docgen docs'), _slots(Style.load('lucid'))))"
	@echo "  open $(HERE)/docs/index.html"

explore: ## OUT/ir.json -> OUT/explore/ — navigate on one side, explore on the other
	@$(RUN) $(PKG).emitters explore $(OUT)/ir.json -o $(OUT)/explore \
	  --style $(STYLE) $(THEME_ARG) --scale $(SCALE)
	@echo "  open $(OUT)/explore/explore.html"

minimap:  ## OUT/ir.json -> OUT/minimap.svg — what is where, read from the colours
	@$(RUN) $(PKG).emitters minimap $(OUT)/ir.json -o $(OUT)/minimap.svg \
	  --style $(STYLE) $(THEME_ARG) --scale $(SCALE)

code:  ## Extract C#/TypeScript from SRC (needs tree-sitter)
	@test -n "$(SRC)" || { echo "Error: set SRC=/path/to/tree" >&2; exit 1; }
	@mkdir -p $(OUT)
	@$(RUN) $(PKG).extractors code --root "$(SRC)" -o $(OUT)/ir.json
	@$(RUN) $(PKG).ir $(OUT)/ir.json

index:  ## OUT/ir.json -> OUT/index.md and OUT/sidebar.json
	@$(RUN) $(PKG).emitters index $(OUT)/ir.json -o $(OUT)/index.md
	@$(RUN) $(PKG).emitters index $(OUT)/ir.json -o $(OUT)/sidebar.json

self:  ## Run the whole pipeline over soleprint itself — the honest end-to-end check
	@$(MAKE) --no-print-directory ir SRC=$(PARENT)/.. OUT=$(OUT)
	@$(MAKE) --no-print-directory index OUT=$(OUT)
	@$(MAKE) --no-print-directory graph OUT=$(OUT)
	@$(MAKE) --no-print-directory site OUT=$(OUT)
	@$(MAKE) --no-print-directory minimap OUT=$(OUT)
	@$(MAKE) --no-print-directory explore OUT=$(OUT)
	@echo
	@echo "  Read $(OUT)/index.md, or open $(OUT)/site/index.html"

doctor:  ## Report whether this machine can run it
	@printf 'python   : '; $(PY) --version 2>&1 || echo MISSING
	@printf 'dot      : '; (dot -V 2>&1) || echo 'MISSING — sudo apt install graphviz (only to render)'
	@printf 'tree-sit : '; $(PY) -c 'import tree_sitter, tree_sitter_c_sharp, tree_sitter_typescript; print("ok — C# and TypeScript available")' 2>/dev/null || echo 'absent — Python only. pip install tree_sitter tree_sitter_c_sharp tree_sitter_typescript'
	@printf 'networkx : '; $(PY) -c 'import networkx; print(networkx.__version__ + " — for lab/ experiments")' 2>/dev/null || echo 'absent — only used in lab/'
	@printf 'package  : %s (from %s)\n' '$(PKG)' '$(PARENT)'
	@printf 'styles   : '; $(RUN) $(PKG).style 2>/dev/null \
	  || $(RUN) $(PKG) 2>/dev/null \
	  || PYTHONPATH=$(PARENT) $(PY) -c "from $(PKG).style import Style; print(', '.join(Style.available()))"
	@PYTHONPATH=$(PARENT) $(PY) -c "import $(PKG).ir, $(PKG).emitters.dot, $(PKG).ops" >/dev/null 2>&1 \
	  && echo 'import   : ok' || echo 'import   : FAILED — is the folder intact?'

clean:  ## Delete OUT. Nothing else is ever written to
	@rm -rf "$(OUT)" && echo "Removed $(OUT)"
