#!/usr/bin/env bash

# Test that wildcard patterns work correctly when tasks have relative :dependency syntax
# e.g., `mise run '//...:format'` where each project's format task has `depends = [":bootstrap"]`
# should resolve :bootstrap to each project's own bootstrap task.

export MISE_EXPERIMENTAL=1

# Create monorepo root config
cat <<'EOF' >mise.toml
monorepo_root = true

[monorepo]
config_roots = ["libs/*", "apps/*", "apps/*/*", "tools/*"]

[settings]
experimental = true

[tasks."groups:tests:root"]
run = 'echo "root grouped test executed"'

[tasks.relative-tests]
depends = [{ task = "./...:groups:tests:*", optional = true }]
run = 'echo "root relative tests executed"'
EOF

# Create first project with format depending on bootstrap
mkdir -p libs/shared
cat <<'EOF' >libs/shared/mise.toml
[tasks.bootstrap]
run = 'echo "shared bootstrap executed"'

[tasks.format]
depends = [":bootstrap"]
run = 'echo "shared format executed"'

[tasks.lint]
depends = [":bootstrap"]
run = 'echo "shared lint executed"'
EOF

# Create second project with same pattern
mkdir -p apps/frontend
cat <<'EOF' >apps/frontend/mise.toml
[tasks.bootstrap]
run = 'echo "frontend bootstrap executed"'

[tasks.format]
depends = [":bootstrap"]
run = 'echo "frontend format executed"'

[tasks.build]
depends = [":bootstrap"]
run = 'echo "frontend build executed"'

[tasks."groups:tests:frontend"]
run = 'echo "frontend grouped test executed"'

[tasks.relative-tests]
depends = [{ task = "./...:groups:tests:*", optional = true }]
run = 'echo "frontend relative tests executed"'

[tasks.relative-bootstrap]
depends = ["./:bootstrap"]
run = 'echo "frontend relative bootstrap executed"'
EOF

# Create a nested project using the same relative dependency declaration
mkdir -p apps/frontend/child
cat <<'EOF' >apps/frontend/child/mise.toml
[tasks."groups:tests:child"]
run = 'echo "child grouped test executed"'

[tasks.relative-tests]
depends = [{ task = "./...:groups:tests:*", optional = true }]
run = 'echo "child relative tests executed"'
EOF

# Create third project with same pattern
mkdir -p apps/backend
cat <<'EOF' >apps/backend/mise.toml
[tasks.bootstrap]
run = 'echo "backend bootstrap executed"'

[tasks.format]
depends = [":bootstrap"]
run = 'echo "backend format executed"'

[tasks.test]
depends = [":format"]
run = 'echo "backend test executed"'

[tasks."groups:tests:backend"]
run = 'echo "backend grouped test executed"'
EOF

# Create a project WITHOUT bootstrap to ensure it doesn't interfere
mkdir -p tools/cli
cat <<'EOF' >tools/cli/mise.toml
[tasks.format]
run = 'echo "cli format executed"'
EOF

# Verify tasks are discovered correctly
assert_contains "mise tasks --all" "//libs/shared:format"
assert_contains "mise tasks --all" "//libs/shared:bootstrap"
assert_contains "mise tasks --all" "//apps/frontend:format"
assert_contains "mise tasks --all" "//apps/frontend:bootstrap"
assert_contains "mise tasks --all" "//apps/backend:format"
assert_contains "mise tasks --all" "//apps/backend:bootstrap"
assert_contains "mise tasks --all" "//tools/cli:format"

# Test 1: Individual task execution works (baseline)
assert_contains "mise run //libs/shared:format" "shared bootstrap executed"
assert_contains "mise run //libs/shared:format" "shared format executed"

assert_contains "mise run //apps/frontend:format" "frontend bootstrap executed"
assert_contains "mise run //apps/frontend:format" "frontend format executed"

assert_contains "mise run //apps/backend:format" "backend bootstrap executed"
assert_contains "mise run //apps/backend:format" "backend format executed"

# Test 2: Wildcard with dependencies should work
assert_contains "mise run '//...:format'" "shared bootstrap executed"
assert_contains "mise run '//...:format'" "shared format executed"
assert_contains "mise run '//...:format'" "frontend bootstrap executed"
assert_contains "mise run '//...:format'" "frontend format executed"
assert_contains "mise run '//...:format'" "backend bootstrap executed"
assert_contains "mise run '//...:format'" "backend format executed"
assert_contains "mise run '//...:format'" "cli format executed"

# Test 3: Partial wildcard with dependencies
assert_contains "mise run '//apps/...:format'" "frontend bootstrap executed"
assert_contains "mise run '//apps/...:format'" "frontend format executed"
assert_contains "mise run '//apps/...:format'" "backend bootstrap executed"
assert_contains "mise run '//apps/...:format'" "backend format executed"

# Test 4: Task name wildcard with dependencies
assert_contains "mise run '//libs/shared:*'" "shared bootstrap executed"
assert_contains "mise run '//libs/shared:*'" "shared format executed"
assert_contains "mise run '//libs/shared:*'" "shared lint executed"

# Test 5: Chained dependencies through wildcards
# backend:test depends on :format which depends on :bootstrap
assert_contains "mise run '//apps/backend:test'" "backend bootstrap executed"
assert_contains "mise run '//apps/backend:test'" "backend format executed"
assert_contains "mise run '//apps/backend:test'" "backend test executed"

# Test 6: Wildcard should work for tasks with chained relative dependencies
assert_contains "mise run '//...:test'" "backend bootstrap executed"
assert_contains "mise run '//...:test'" "backend format executed"
assert_contains "mise run '//...:test'" "backend test executed"

# Test 7: ./ paths in dependencies resolve relative to the declaring task
assert_contains "mise run '//apps/frontend:relative-tests'" "frontend grouped test executed"
assert_contains "mise run '//apps/frontend:relative-tests'" "child grouped test executed"
assert_not_contains "mise run '//apps/frontend:relative-tests'" "backend grouped test executed"
assert_not_contains "mise run '//apps/frontend:relative-tests'" "root grouped test executed"

# ./ followed directly by a task separator stays in the declaring project
assert_contains "mise run '//apps/frontend:relative-bootstrap'" "frontend bootstrap executed"
assert_contains "mise run '//apps/frontend:relative-bootstrap'" "frontend relative bootstrap executed"
assert_not_contains "mise run '//apps/frontend:relative-bootstrap'" "shared bootstrap executed"
assert_not_contains "mise run '//apps/frontend:relative-bootstrap'" "backend bootstrap executed"

assert_contains "mise run '//apps/frontend/child:relative-tests'" "child grouped test executed"
assert_not_contains "mise run '//apps/frontend/child:relative-tests'" "frontend grouped test executed"
assert_not_contains "mise run '//apps/frontend/child:relative-tests'" "backend grouped test executed"

assert_contains "mise run '//:relative-tests'" "root grouped test executed"
assert_contains "mise run '//:relative-tests'" "frontend grouped test executed"
assert_contains "mise run '//:relative-tests'" "child grouped test executed"
assert_contains "mise run '//:relative-tests'" "backend grouped test executed"

echo "=== All wildcard with dependencies tests passed! ==="
