# 羽藏 FeatherVault 的建置與測試。
GO      ?= $(shell command -v go 2>/dev/null || echo $(HOME)/.local/opt/go/bin/go)
NODEBIN ?= $(shell dirname "$$(command -v npm 2>/dev/null || echo $(HOME)/.local/opt/node/bin/npm)")
MODULE  := gitea.jsc.idv.tw/jiantw83/feather-vault
VERSION ?= $(shell git describe --tags --exact-match 2>/dev/null || echo dev)
COMMIT  ?= $(shell git rev-parse --short HEAD 2>/dev/null)
LDFLAGS := -s -w -X $(MODULE)/internal/version.Version=$(VERSION) -X $(MODULE)/internal/version.Commit=$(COMMIT)

# 沒有 sudo 的主機用 scripts/chromium-deps.sh 把 Chromium 的相依套件裝在使用者目錄。
CHROMIUM_DEPS ?= $(HOME)/.local/opt/chromium-deps
ifneq ($(wildcard $(CHROMIUM_DEPS)/fonts.conf),)
export LD_LIBRARY_PATH := $(CHROMIUM_DEPS)/root/usr/lib/x86_64-linux-gnu
export FONTCONFIG_FILE := $(CHROMIUM_DEPS)/fonts.conf
endif
export PATH := $(NODEBIN):$(PATH)

# 平行執行的測試數；每個測試都有自己的假 X 網站與瀏覽器分頁，太多會互相搶 CPU 而逾時
TEST_PARALLEL ?= 4

.PHONY: icons web test-shard build publish-go style-qa style-report test test-styles test-smb test-pg test-realx probe-realx run typecheck binaries dist release

web: ## 編譯前端到 web/dist
	cd web && npm ci && npm run build

typecheck: ## TypeScript、go vet，並檢查介面文字都在語系檔、圖示都在字型子集、風格對比度
	cd web && npm run typecheck && npm run check-i18n && npm run check-icons && npm run check-brand-icons && npm run check-contrast && npm run check-style-previews && npm run check-anime-styles && npm run check-css-budget && npm run check-people-offline
	$(GO) vet ./...

build: web ## 編譯單一執行檔 bin/feathervault
	$(GO) build -ldflags "$(LDFLAGS)" -o bin/feathervault ./cmd/feathervault

icons: ## 重新產生圖示字型子集（新增圖示後執行）
	cd web && npm run icons

test: web ## 執行全部測試（包含用瀏覽器的 UI 測試）
	cd web && npm run check-i18n && npm run check-icons && npm run check-brand-icons && npm run check-contrast && npm run check-style-previews && npm run check-anime-styles && npm run check-css-budget && npm run check-people-offline && npm run test:unit
	$(GO) vet ./...
	$(GO) test -timeout 60m -parallel $(TEST_PARALLEL) ./... # internal/app 的黑箱測試會開真的瀏覽器；testenv.Start 讓測試平行執行（FV_SERIAL=1 改回串行）

# 分成 N 份，只跑第 K 份 internal/app 的測試（CI 同時開多個工作）：make test-shard K=1 N=3
test-shard: web ## 只執行 internal/app 測試的第 K／N 份
	scripts/test-shard.sh $(K) $(N) -parallel $(TEST_PARALLEL)

# 全部風格（原本 10 種加動漫角色風格）；和 web/src/appearanceStore.ts 的 STYLE_IDS 一致
STYLES := material glass graphite gallery paper contrast soft brutal swiss retro asuna leafa yui lisbeth silica sinon yuuki alice ronye tiese selka deviluke mikan haruna yami risa ryoko mea roxy eris sylphy norn aisha norn-aisha emilia rem ram rem-ram beatrice petra kirino ruri ayase kanako kirino-ruri kirino-ayase miko azki aki haato fubuki matsuri ayame aqua shion mio okayu korone pekora noel marine watame luna kanata lamy nene botan polka koyori chloe ririka riona su chihaya vivi tsuzuri kiara amelia gura fubuki-mio okayu-korone fubuki-mio-okayu-korone

test-styles: web ## 每種風格（淺色、深色）跑 UI 測試：手機 360px 與桌面寬度的水平捲動檢查，截圖存到 bin/style-shots（FV_SHOT_DIR 可改）
	@fail=0; for s in $(STYLES); do for sc in light dark; do \
		echo "== 風格 $$s、主題 $$sc =="; \
		FV_STYLE=$$s FV_SCHEME=$$sc FV_SHOT_DIR=$${FV_SHOT_DIR:-$(CURDIR)/bin/style-shots} \
			$(GO) test ./internal/app/ -count=1 -timeout 60m -run 'TestStyleMatrix|TestNavigationWorksOnDesktopAndPhoneWidths|TestSystemLogPageShowsNewEventsLive|TestDashboardDiscovery|TestDatabaseAttachCardIsSeparate' || { echo "失敗：風格 $$s、主題 $$sc"; fail=1; }; \
	done; done; exit $$fail

run: build
	./bin/feathervault serve

test-smb: ## 用 .env.test 的 NAS 帳密，對真實 NAS 跑 SMB 契約測試
	@test -f .env.test || { echo "請先照 .env.test.example 建立 .env.test"; exit 1; }
	set -a; . ./.env.test; set +a; $(GO) test ./internal/storage/ -run TestSMBStoreContract -v -count=1

test-pg: ## 用 .env.pg 的連線對真實 PostgreSQL 跑契約測試，再把整套 internal/app 黑箱測試在 PostgreSQL 上跑一次（手動執行）
	@test -f .env.pg || { echo "請先照 .env.pg.example 建立 .env.pg"; exit 1; }
	set -a; . ./.env.pg; set +a; $(GO) test ./internal/db/... ./internal/tags/ ./internal/app/ -run TestPostgresContract -v -count=1
	@# 黑箱測試（含 UI 測試）要和 SQLite 一樣全綠，就地替換正式資料庫的還原測試在 PostgreSQL 模式先 skip（改走匯入狀態機，由 #227 的還原管線接上）；仍列出失敗的測試方便排查
	@mkdir -p bin
	-set -a; . ./.env.pg; set +a; $(GO) test -tags pg ./internal/app/ -count=1 -timeout 60m 2>&1 | tee bin/test-pg-app.log | grep -E '^(--- FAIL|ok|FAIL|panic:)'
	@echo "在 PostgreSQL 上失敗的黑箱測試（完整輸出在 bin/test-pg-app.log）："
	@grep -E '^--- FAIL' bin/test-pg-app.log | sed -E 's/^--- FAIL: ([^ ]+).*/  \1/' | sort -u
	@echo "共 $$(grep -cE '^--- FAIL' bin/test-pg-app.log) 個；$$(grep -qE '^panic:|test timed out' bin/test-pg-app.log && echo '測試程式中途結束（panic 或逾時），清單不完整' || echo '全部測試都有執行')"
	@! grep -qE '^(--- FAIL|FAIL|panic:|test timed out)' bin/test-pg-app.log || { echo "黑箱測試在 PostgreSQL 上沒有全綠"; exit 1; }

style-qa: ## 預覽頁每個風格 × 7 個頁面 × W／M 的水平溢位檢查，並拼 W／M 總覽圖到 bin/style-qa/（先要有 web/dist 與 sao-scenes.json，見 build-sao.mjs）
	FV_PREVIEW_OUT=styles-all.html node design/preview/styles/build-sao.mjs
	$(GO) run ./scripts/style-qa design/preview/styles-all.html bin/style-qa

style-report: ## 把 bin/style-qa/ 的輸出整理成一頁 bin/style-qa/report.html（摘要、問題、切換耗時、截圖、角色資料複查；先跑 make style-qa）
	cd web && npm run style-report

test-realx: ## 用 .env.realx 的 X 帳號和範例，對真實的 X 跑一次初次解析並回報結果（手動執行）
	@test -f .env.realx || { echo "請先照 .env.realx.example 建立 .env.realx"; exit 1; }
	set -a; . ./.env.realx; set +a; $(GO) test ./internal/app/ -run TestRealXSmoke -v -count=1 -timeout 3h

probe-realx: ## 用 .env.realx 的 X 帳號打開首頁與指定的使用者、社群，列出帳號狀態與個人檔案連結相關的 GraphQL 欄位（手動執行，#63、#113）
	@test -f .env.realx || { echo "請先照 .env.realx.example 建立 .env.realx"; exit 1; }
	set -a; . ./.env.realx; set +a; $(GO) test ./internal/app/ -run TestRealXAccountStatus -v -count=1 -timeout 1h

# 發佈：兩個 Linux 執行檔（前端已包進去，純 Go 不需要 cgo，可以直接交叉編譯）與檢查碼放在 dist/
DIST := dist
binaries: web ## 交叉編譯兩個 Linux 執行檔到 dist/
	rm -rf $(DIST) && mkdir -p $(DIST)
	CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GO) build -trimpath -ldflags "$(LDFLAGS)" -o $(DIST)/feathervault-linux-x64 ./cmd/feathervault
	CGO_ENABLED=0 GOOS=linux GOARCH=arm64 $(GO) build -trimpath -ldflags "$(LDFLAGS)" -o $(DIST)/feathervault-linux-arm64 ./cmd/feathervault

dist: binaries ## 發佈用的全部檔案：linux-x64、linux-arm64 執行檔、SHA256SUMS
	cd $(DIST) && sha256sum feathervault-* > SHA256SUMS
	@cat $(DIST)/SHA256SUMS

release: ## 在 Gitea Releases 發佈目前 HEAD 上的標籤，例如 git tag v0.1.0 && make release
	@git describe --tags --exact-match >/dev/null 2>&1 || { echo "HEAD 沒有標籤：請先 git tag vX.Y.Z"; exit 1; }
	$(MAKE) dist
	scripts/release.sh $(VERSION) $(DIST)

publish-go: web ## 把目前 HEAD 上的標籤發佈到 Gitea 的 Go 套件庫，例如 git tag v0.0.1 && GITEA_TOKEN=... make publish-go
	@tag=$$(git describe --tags --exact-match 2>/dev/null) || { echo "HEAD 沒有標籤：請先 git tag vX.Y.Z"; exit 1; }; scripts/publish-go.sh $$tag
