#!/usr/bin/env bash

# An [env] module whose plugin is not installed and has no known source
# must not break every command. mise warns, skips the module, and keeps
# working, so `mise plugins link`/`install` can still fix it.

cat >mise.toml <<'EOF'
[env]
_.not-a-real-env-plugin = {}
FOO = "bar"
EOF

assert_contains "mise env -s bash" "export FOO=bar"
assert_contains "mise env -s bash 2>&1" "skipping env plugin not-a-real-env-plugin"
assert_contains "mise env -s bash 2>&1" "mise plugins install not-a-real-env-plugin"
assert "mise x -- echo hi" "hi"
assert_succeed "mise ls"
assert_fail_contains "mise doctor" "env plugin not-a-real-env-plugin is not installed and has no source"

# Installing the plugin makes the module work.
PLUGIN_SRC="$PWD/env-plugin-src"
mkdir -p "$PLUGIN_SRC/hooks"
cat >"$PLUGIN_SRC/metadata.lua" <<'EOF'
PLUGIN = {}
PLUGIN.name = "not-a-real-env-plugin"
PLUGIN.version = "1.0.0"
PLUGIN.homepage = "https://example.com"
PLUGIN.license = "MIT"
PLUGIN.description = "Test env plugin"
PLUGIN.minRuntimeVersion = "0.3.0"
EOF
cat >"$PLUGIN_SRC/hooks/mise_env.lua" <<'EOF'
function PLUGIN:MiseEnv(ctx)
    return {
        env = {
            {key = "FROM_ENV_PLUGIN", value = "yes"}
        }
    }
end
EOF

assert_succeed "mise plugins link not-a-real-env-plugin $PLUGIN_SRC"
assert_contains "mise env -s bash" "export FROM_ENV_PLUGIN=yes"
assert_not_contains "mise env -s bash 2>&1" "skipping env plugin"
assert_not_contains "mise doctor 2>&1 || true" "env plugin not-a-real-env-plugin"

# An installed plugin that fails is still an error.
cat >"$PLUGIN_SRC/hooks/mise_env.lua" <<'EOF'
function PLUGIN:MiseEnv(ctx)
    error("env plugin exploded")
end
EOF
assert_fail_contains "mise env -s bash" "env plugin exploded"

# A plugin with a known source that cannot be installed is still an error,
# so a command never runs without an env it expects (secrets, credentials).
cat >mise.toml <<EOF
[plugins]
unreachable-env-plugin = "$PWD/does-not-exist"

[env]
_.unreachable-env-plugin = {}

[tasks.deploy]
run = "echo SECRET=\${SECRET:-missing}"
EOF
export MISE_YES=1
assert_fail_contains "mise env -s bash" "local plugin directory does not exist"
assert_fail "mise run deploy" "local plugin directory does not exist"
assert_not_contains "mise run deploy 2>&1 || true" "SECRET=missing"
assert_not_contains "mise env -s bash 2>&1 || true" "skipping env plugin"

# The same for an owner/repo source whose clone fails.
cat >mise.toml <<'EOF'
[env]
_."jdx/mise-e2e-missing-env-plugin" = {}

[tasks.deploy]
run = "echo SECRET=${SECRET:-missing}"
EOF
assert_fail "mise run deploy"
assert_not_contains "mise run deploy 2>&1 || true" "SECRET=missing"
assert_not_contains "mise env -s bash 2>&1 || true" "skipping env plugin"

# A [plugins] entry with a malformed URL is a source, so it errors instead of
# being skipped.
cat >mise.toml <<'EOF'
[plugins]
typo-env-plugin = "htps://github.com/acme/env"

[env]
_.typo-env-plugin = {}
EOF
assert_fail "mise env -s bash"
assert_not_contains "mise env -s bash 2>&1 || true" "skipping env plugin"

# Safe mode ignores project [env] modules, so doctor does not report them.
# (not-a-real-env-plugin is linked above, so use a fresh name.)
cat >mise.toml <<'EOF'
[env]
_.unlinked-env-plugin = {}
EOF
assert_contains "mise doctor 2>&1 || true" "env plugin unlinked-env-plugin"
assert_not_contains "MISE_SAFE=1 mise doctor 2>&1 || true" "env plugin unlinked-env-plugin"
