#!/usr/bin/env bash

# Test mise prepare (mise prep) command

# Test --list with no providers configured
assert_contains "mise prepare --list" "No prepare providers found"

# Create a package-lock.json (npm provider needs to be configured to detect it)
cat >package-lock.json <<'EOF'
{
  "name": "test-project",
  "lockfileVersion": 3,
  "packages": {}
}
EOF

# Still no providers without explicit config
assert_contains "mise prepare --list" "No prepare providers found"

# Configure npm provider explicitly
cat >mise.toml <<'EOF'
[prepare.npm]
EOF

# Now npm provider should be detected
assert_contains "mise prepare --list" "npm"
assert_contains "mise prepare --list" "package-lock.json"
assert_contains "mise prepare --list" "node_modules"

# Test --dry-run shows what would run
assert_contains "mise prepare --dry-run" "npm"

# Test alias works
assert_contains "mise prep --list" "npm"

# Test with custom prepare provider (no .rules. prefix)
cat >mise.toml <<'EOF'
[prepare.npm]

[prepare.codegen]
sources = ["schema.graphql"]
outputs = ["generated/"]
run = "echo codegen"
EOF

# Create source file
touch schema.graphql

assert_contains "mise prepare --list" "codegen"
assert_contains "mise prepare --list" "schema.graphql"

# Test --only flag
assert_contains "mise prepare --dry-run --only codegen" "codegen"
assert_not_contains "mise prepare --dry-run --only codegen" "npm"

# Test --skip flag
assert_not_contains "mise prepare --dry-run --skip npm" "npm install"

# Test disable in config
cat >mise.toml <<'EOF'
[prepare]
disable = ["npm"]

[prepare.npm]

[prepare.codegen]
sources = ["schema.graphql"]
outputs = ["generated/"]
run = "echo codegen"
EOF

assert_not_contains "mise prepare --list" "npm"
assert_contains "mise prepare --list" "codegen"

# Test per-provider auto flag
cat >mise.toml <<'EOF'
[prepare.npm]
auto = true

[prepare.codegen]
auto = false
sources = ["schema.graphql"]
outputs = ["generated/"]
run = "echo codegen"
EOF

# Both should show in list
assert_contains "mise prepare --list" "npm"
assert_contains "mise prepare --list" "codegen"

# Test yarn provider
rm -f package-lock.json
cat >yarn.lock <<'EOF'
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
EOF

cat >mise.toml <<'EOF'
[prepare.yarn]
EOF

assert_contains "mise prepare --list" "yarn"
assert_contains "mise prepare --list" "yarn.lock"
assert_contains "mise prepare --dry-run" "yarn"

# Test pnpm provider
rm -f yarn.lock
cat >pnpm-lock.yaml <<'EOF'
lockfileVersion: '9.0'
EOF

cat >mise.toml <<'EOF'
[prepare.pnpm]
EOF

assert_contains "mise prepare --list" "pnpm"
assert_contains "mise prepare --list" "pnpm-lock.yaml"
assert_contains "mise prepare --dry-run" "pnpm"

# Test bun provider (binary lockfile)
rm -f pnpm-lock.yaml
touch bun.lockb

cat >mise.toml <<'EOF'
[prepare.bun]
EOF

assert_contains "mise prepare --list" "bun"
assert_contains "mise prepare --list" "bun.lockb"
assert_contains "mise prepare --dry-run" "bun"

# Test bun provider (text lockfile)
rm -f bun.lockb
cat >bun.lock <<'EOF'
# bun lockfile
EOF

assert_contains "mise prepare --list" "bun"
assert_contains "mise prepare --list" "bun.lock"

# Test go provider
rm -f bun.lock
cat >go.sum <<'EOF'
github.com/foo/bar v1.0.0 h1:abc
EOF
cat >go.mod <<'EOF'
module test
go 1.21
EOF
# Ensure go.sum (output) is older than go.mod (source) to trigger staleness
touch -t 202301010000 go.sum

cat >mise.toml <<'EOF'
[prepare.go]
EOF

assert_contains "mise prepare --list" "go"
assert_contains "mise prepare --list" "go.sum"
assert_contains "mise prepare --dry-run" "go"

# Test pip provider
rm -f go.sum go.mod
cat >requirements.txt <<'EOF'
requests==2.31.0
EOF

cat >mise.toml <<'EOF'
[prepare.pip]
EOF

assert_contains "mise prepare --list" "pip"
assert_contains "mise prepare --list" "requirements.txt"
assert_contains "mise prepare --dry-run" "pip"

# Test poetry provider
rm -f requirements.txt
cat >poetry.lock <<'EOF'
[[package]]
name = "requests"
version = "2.31.0"
EOF
cat >pyproject.toml <<'EOF'
[tool.poetry]
name = "test"
EOF

cat >mise.toml <<'EOF'
[prepare.poetry]
EOF

assert_contains "mise prepare --list" "poetry"
assert_contains "mise prepare --list" "poetry.lock"
assert_contains "mise prepare --dry-run" "poetry"

# Test uv provider
rm -f poetry.lock
cat >uv.lock <<'EOF'
version = 1
EOF

cat >mise.toml <<'EOF'
[prepare.uv]
EOF

assert_contains "mise prepare --list" "uv"
assert_contains "mise prepare --list" "uv.lock"
assert_contains "mise prepare --dry-run" "uv"

# Test bundler provider
rm -f uv.lock pyproject.toml
cat >Gemfile.lock <<'EOF'
GEM
  specs:
EOF
cat >Gemfile <<'EOF'
source 'https://rubygems.org'
EOF

cat >mise.toml <<'EOF'
[prepare.bundler]
EOF

assert_contains "mise prepare --list" "bundler"
assert_contains "mise prepare --list" "Gemfile.lock"
assert_contains "mise prepare --dry-run" "bundler"

# Test composer provider
rm -f Gemfile.lock Gemfile
cat >composer.lock <<'EOF'
{
    "_readme": ["This file locks the dependencies"]
}
EOF
cat >composer.json <<'EOF'
{}
EOF

cat >mise.toml <<'EOF'
[prepare.composer]
EOF

assert_contains "mise prepare --list" "composer"
assert_contains "mise prepare --list" "composer.lock"
assert_contains "mise prepare --dry-run" "composer"

# Test freshness detection with output directories
rm -f composer.lock composer.json

cat >mise.toml <<'EOF'
[prepare.custom_venv]
sources = ["requirements.txt"]
outputs = [".venv"]
run = "echo PREPARE_RAN"
EOF

cat >requirements.txt <<'EOF'
requests==2.31.0
EOF

# Test 1: No output directory exists → should be stale
rm -rf .venv
assert_contains "mise prepare --dry-run" "custom_venv"

# Test 2: Output exists and is newer than sources → should be fresh
# Use explicit timestamps: source=2023, output=2024
mkdir -p .venv
touch -t 202301010000 requirements.txt # Jan 1, 2023
touch -t 202401010000 .venv/pyvenv.cfg # Jan 1, 2024 (newer)
# In dry-run mode, fresh providers produce no output, so check provider name is absent
assert_not_contains "mise prepare --dry-run" "custom_venv"

# Test 3: Sources updated after output → should be stale
# source=2025 (newer than output=2024)
touch -t 202501010000 requirements.txt # Jan 1, 2025
assert_contains "mise prepare --dry-run" "custom_venv"

# Clean up
rm -rf .venv requirements.txt
rm -f composer.lock composer.json package.json mise.toml schema.graphql
