# Copyright (c) 2026 Lark Technologies Pte. Ltd.
# SPDX-License-Identifier: MIT

BINARY   := lark-cli
MODULE   := github.com/larksuite/cli
VERSION  := $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
DATE     := $(shell date +%Y-%m-%d)
NODE     ?= node
QUALITY_GATE_CHANGED_FROM ?= $(shell bash scripts/resolve-changed-from.sh)
QUALITY_GATE_CHANGED_FROM_RESOLVED = $(if $(strip $(QUALITY_GATE_CHANGED_FROM)),$(QUALITY_GATE_CHANGED_FROM),$(shell bash scripts/resolve-changed-from.sh))
QUALITY_GATE_DIR ?= .tmp/quality-gate
QUALITY_GATE_MANIFEST_OUT ?= $(QUALITY_GATE_DIR)/command-manifest.json
QUALITY_GATE_COMMAND_INDEX_OUT ?= $(QUALITY_GATE_DIR)/command-index.json
QUALITY_GATE_FACTS_OUT ?= $(QUALITY_GATE_DIR)/facts.json
PUBLIC_CONTENT_METADATA ?= $(QUALITY_GATE_DIR)/public-content-metadata.json
LDFLAGS  := -s -w -X $(MODULE)/internal/build.Version=$(VERSION) -X $(MODULE)/internal/build.Date=$(DATE)
PREFIX   ?= /usr/local

# The repository's Go 1.23 CI toolchain does not support -race on riscv64.
# Prefer GOARCH passed to make (for example, `make GOARCH=riscv64 unit-test`)
# over `go env GOARCH`, because command-line make variables are not visible to
# $(shell ...).
TEST_GOARCH := $(or $(GOARCH),$(shell go env GOARCH))
RACE_FLAG := $(if $(filter riscv64,$(TEST_GOARCH)),,-race)

.PHONY: all build vet fmt-check script-test test unit-test integration-test examples-build quality-gate install uninstall clean fetch_meta gitleaks

all: test

fetch_meta:
	python3 scripts/fetch_meta.py

build: fetch_meta
	go build -trimpath -ldflags "$(LDFLAGS)" -o $(BINARY) .

vet: fetch_meta
	go vet ./...

# fmt-check fails when any file would be reformatted by gofmt. Keep this
# in sync with the fast-gate "Check formatting" step in CI.
fmt-check:
	@unformatted=$$(gofmt -l . | grep -v '^\.claude/' || true); \
	if [ -n "$$unformatted" ]; then \
		echo "Unformatted Go files:"; \
		echo "$$unformatted"; \
		echo "Run 'gofmt -w .' and commit."; \
		exit 1; \
	fi

script-test:
	bash scripts/resolve-changed-from.test.sh
	bash scripts/ci-workflow.test.sh
	bash scripts/semantic-review-workflow.test.sh
	$(NODE) --test scripts/semantic-review-verify-artifact.test.js scripts/pr-quality-summary.test.js scripts/semantic-review-publish.test.js scripts/ci-quality-summary-publish.test.js

# ./extension/... keeps the public plugin SDK in the default test matrix.
unit-test: fetch_meta
	go test $(RACE_FLAG) -gcflags="all=-N -l" -count=1 \
		./cmd/... ./internal/... ./shortcuts/... ./extension/...

# examples-build keeps the shipped plugin-SDK examples compilable. If this
# breaks, the plugin author guide's "go build ./..." path is broken.
examples-build:
	go build ./extension/platform/examples/audit-observer
	go build ./extension/platform/examples/readonly-policy

integration-test: build
	go test -v -count=1 ./tests/...

test: vet fmt-check script-test unit-test examples-build integration-test

quality-gate: build
	mkdir -p $(QUALITY_GATE_DIR) $(dir $(QUALITY_GATE_FACTS_OUT)) $(dir $(PUBLIC_CONTENT_METADATA))
	test -f $(PUBLIC_CONTENT_METADATA) || printf '{}\n' > $(PUBLIC_CONTENT_METADATA)
	LARKSUITE_CLI_REMOTE_META=off \
	LARKSUITE_CLI_NO_UPDATE_NOTIFIER=1 \
	LARKSUITE_CLI_NO_SKILLS_NOTIFIER=1 \
	go run ./internal/qualitygate/cmd/manifest-export \
		--manifest-out $(QUALITY_GATE_MANIFEST_OUT) \
		--command-index-out $(QUALITY_GATE_COMMAND_INDEX_OUT)
	LARKSUITE_CLI_APP_ID=dry-run \
	LARKSUITE_CLI_APP_SECRET=dry-run \
	LARKSUITE_CLI_BRAND=feishu \
	LARKSUITE_CLI_CONFIG_DIR=$${TMPDIR:-/tmp}/quality-gate-cli-config \
	LARKSUITE_CLI_REMOTE_META=off \
	LARKSUITE_CLI_NO_UPDATE_NOTIFIER=1 \
	LARKSUITE_CLI_NO_SKILLS_NOTIFIER=1 \
	go run ./internal/qualitygate/cmd/quality-gate check \
		--repo . \
		--cli-bin ./$(BINARY) \
		--changed-from $(QUALITY_GATE_CHANGED_FROM_RESOLVED) \
		--manifest $(QUALITY_GATE_MANIFEST_OUT) \
		--command-index $(QUALITY_GATE_COMMAND_INDEX_OUT) \
		--public-content-metadata $(PUBLIC_CONTENT_METADATA) \
		--facts-out $(QUALITY_GATE_FACTS_OUT)

install: build
	install -d $(PREFIX)/bin
	install -m755 $(BINARY) $(PREFIX)/bin/$(BINARY)
	@echo "OK: $(PREFIX)/bin/$(BINARY) ($(VERSION))"

uninstall:
	rm -f $(PREFIX)/bin/$(BINARY)

clean:
	rm -f $(BINARY)

# Run secret-leak checks locally before pushing.
# Step 1: check-doc-tokens catches realistic-looking example tokens in reference
#         docs and asks you to use _EXAMPLE_TOKEN placeholders instead.
# Step 2: gitleaks scans the full repo for real leaked secrets.
# Install gitleaks: https://github.com/gitleaks/gitleaks#installing
gitleaks:
	@bash scripts/check-doc-tokens.sh
	@command -v gitleaks >/dev/null 2>&1 || { echo "gitleaks not found. Install: brew install gitleaks"; exit 1; }
	gitleaks detect --redact -v --exit-code=2
