#!/usr/bin/env bash
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)"
GUARD="$ROOT/guardrails/architecture/check-meshx-runtime-topology.sh"
FIXTURE="$(mktemp -d)"
trap 'rm -rf "$FIXTURE"' EXIT

reset_fixture() {
  rm -rf "$FIXTURE/meshx" "$FIXTURE/internal/meshx" "$FIXTURE/internal/resource"
  rm -f "$FIXTURE/go.mod" "$FIXTURE/go.sum"
  mkdir -p "$FIXTURE/internal/resource/server" "$FIXTURE/x/proc"
}

expect_failure() {
  local label="$1"
  if AGENTTEAM_MESHX_RUNTIME_TOPOLOGY_ROOT="$FIXTURE" bash "$GUARD" >/dev/null 2>&1; then
    echo "expected $label fixture to fail" >&2
    exit 1
  fi
}

write_failure() {
  local label="$1"
  reset_fixture
  cat >"$FIXTURE/internal/resource/server/server.go"
  expect_failure "$label"
}

write_failure "cross-function aliased net.Listen and http.Serve" <<'EOF'
package server
import (network "net"; web "net/http")
func newListener() (network.Listener, error) { return network.Listen("tcp", ":3002") }
func run(listener network.Listener) error { return web.Serve(listener, web.NewServeMux()) }
EOF

write_failure "aliased tls.Listen" <<'EOF'
package server
import secure "crypto/tls"
var listen = secure.Listen
EOF

reset_fixture
cat >"$FIXTURE/internal/resource/server/types.go" <<'EOF'
package server
import web "net/http"
type Server struct { HTTP *web.Server }
EOF
cat >"$FIXTURE/internal/resource/server/run.go" <<'EOF'
package server
import "net"
func (server *Server) run(listener net.Listener) error { return server.HTTP.Serve(listener) }
EOF
expect_failure "cross-file http.Server field"

write_failure "http.Server factory" <<'EOF'
package server
import ("net"; "net/http")
func makeServer() *http.Server { return nil }
func run(listener net.Listener) error { return makeServer().Serve(listener) }
EOF

write_failure "package-level http.Server" <<'EOF'
package server
import ("net"; "net/http")
var server *http.Server
func run(listener net.Listener) error { return server.Serve(listener) }
EOF

write_failure "net.ListenConfig" <<'EOF'
package server
import "net"
func run(config net.ListenConfig) { _, _ = config.Listen(nil, "tcp", ":3002") }
EOF

write_failure "http.Server method value" <<'EOF'
package server
import "net/http"
func bindServe(server *http.Server) { _ = server.Serve }
EOF

for primitive in Serve ServeTLS ListenAndServe ListenAndServeTLS; do
  write_failure "net/http $primitive primitive" <<EOF
package server
import web "net/http"
var forbidden = web.$primitive
EOF
done

for import_path in net crypto/tls net/http; do
  write_failure "$import_path dot import" <<EOF
package server
import . "$import_path"
EOF
done

write_failure "listener ownership with business Serve" <<'EOF'
package server
import "net"
type Business struct{}
func (Business) Serve(net.Listener) error { return nil }
func run(business Business) error {
	listener, err := net.Listen("tcp", ":3002")
	if err != nil { return err }
	return business.Serve(listener)
}
EOF

reset_fixture
cat >"$FIXTURE/internal/resource/server/server.go" <<'EOF'
package server
import ("net/http"; "strings"; "time")
type Business struct{}
type localHTTP struct{ Server string }
func (Business) Serve(any) error { return nil }
func shadow(http localHTTP) string { return http.Server }
func Handler() http.Handler {
	return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		http.ServeContent(writer, request, "fixture", time.Time{}, strings.NewReader("ok"))
	})
}
func serveBusiness(business Business, request any) error { return business.Serve(request) }
EOF

AGENTTEAM_MESHX_RUNTIME_TOPOLOGY_ROOT="$FIXTURE" bash "$GUARD" >/dev/null

mkdir -p "$FIXTURE/meshx"
expect_failure "retired MeshX physical root"
rmdir "$FIXTURE/meshx"

for active_path in specs/stale.md docs/development.md; do
  mkdir -p "$FIXTURE/$(dirname "$active_path")"
  echo 'old path: meshx/runtime' >"$FIXTURE/$active_path"
  expect_failure "retired MeshX active path in $active_path"
  rm "$FIXTURE/$active_path"
done

mkdir -p "$FIXTURE/internal/foo"
echo 'package foo; const stale = "meshx/runtime"' >"$FIXTURE/internal/foo/foo_test.go"
expect_failure "retired MeshX path in Go test"
rm -rf "$FIXTURE/internal/foo"

mkdir -p "$FIXTURE/e2e"
echo 'old path: meshx/runtime' >"$FIXTURE/e2e/stale.txt"
expect_failure "retired MeshX path in e2e"
rm -rf "$FIXTURE/e2e"

mkdir -p "$FIXTURE/internal/meshx/legacy"
expect_failure "retired internal/meshx namespace"

reset_fixture
cat >"$FIXTURE/internal/resource/server/retired_module.go" <<'EOF'
package server
import _ "go.pingcap.cn/meshx/runtime"
EOF
expect_failure "retired external MeshX module import"

reset_fixture
cat >"$FIXTURE/go.mod" <<'EOF'
module github.com/tidbcloud/AgentTeam

go 1.26

require go.pingcap.cn/meshx v0.0.0
EOF
expect_failure "root go.mod require of retired MeshX module"

reset_fixture
cat >"$FIXTURE/go.mod" <<'EOF'
module github.com/tidbcloud/AgentTeam

go 1.26

replace go.pingcap.cn/meshx => ./legacy-meshx
EOF
expect_failure "root go.mod replace of retired MeshX module"

for module_file in go.mod go.sum; do
  reset_fixture
  : >"$FIXTURE/internal/resource/server/$module_file"
  expect_failure "resource server nested $module_file"
done

echo "MeshX unified-runtime topology guardrail tests passed"
