package infra

import (
	"strings"
	"testing"
)

func TestGenerateTraefikDynamic(t *testing.T) {
	t.Run("render con auth y gzip", func(t *testing.T) {
		cfg := TraefikDynamicConfig{
			Name:          "registry-api",
			Domain:        "registry.organic-machine.com",
			UpstreamURL:   "http://registry-api:8420",
			BasicAuthLine: "lucas:$2a$10$hashedpassword",
			EnableGzip:    true,
			CertResolver:  "letsencrypt",
		}
		got := GenerateTraefikDynamic(cfg)

		checks := []string{
			"http:",
			"  routers:",
			"    registry-api-http:",
			`      rule: "Host(` + "`registry.organic-machine.com`" + `)"`,
			`        - "http"`,
			`        - "registry-api-redirect"`,
			`      service: "registry-api-service"`,
			"    registry-api-https:",
			`        - "https"`,
			`        - "registry-api-auth"`,
			`        - "registry-api-gzip"`,
			"        certResolver: letsencrypt",
			"  services:",
			"    registry-api-service:",
			`          - url: "http://registry-api:8420"`,
			"  middlewares:",
			"    registry-api-redirect:",
			`        scheme: "https"`,
			"    registry-api-auth:",
			"      basicAuth:",
			"        users:",
			`          - "lucas:$2a$10$hashedpassword"`,
			"    registry-api-gzip:",
			"      compress: true",
		}
		for _, want := range checks {
			if !strings.Contains(got, want) {
				t.Errorf("missing %q in output:\n%s", want, got)
			}
		}
	})

	t.Run("render sin auth", func(t *testing.T) {
		cfg := TraefikDynamicConfig{
			Name:          "myapp",
			Domain:        "myapp.example.com",
			UpstreamURL:   "http://myapp:9000",
			BasicAuthLine: "",
			EnableGzip:    true,
			CertResolver:  "letsencrypt",
		}
		got := GenerateTraefikDynamic(cfg)

		if strings.Contains(got, "basicAuth") {
			t.Errorf("expected no basicAuth when BasicAuthLine is empty, got:\n%s", got)
		}
		if strings.Contains(got, "myapp-auth") {
			t.Errorf("expected no myapp-auth middleware when BasicAuthLine is empty, got:\n%s", got)
		}
		if !strings.Contains(got, "myapp-gzip") {
			t.Errorf("expected myapp-gzip middleware, got:\n%s", got)
		}
		// redirect should always be present
		if !strings.Contains(got, "myapp-redirect") {
			t.Errorf("expected myapp-redirect middleware, got:\n%s", got)
		}
	})

	t.Run("render sin gzip", func(t *testing.T) {
		cfg := TraefikDynamicConfig{
			Name:          "api",
			Domain:        "api.example.com",
			UpstreamURL:   "http://api:8080",
			BasicAuthLine: "admin:$2a$10$hash",
			EnableGzip:    false,
			CertResolver:  "letsencrypt",
		}
		got := GenerateTraefikDynamic(cfg)

		if strings.Contains(got, "api-gzip") {
			t.Errorf("expected no api-gzip middleware when EnableGzip is false, got:\n%s", got)
		}
		if strings.Contains(got, "compress:") {
			t.Errorf("expected no compress section when EnableGzip is false, got:\n%s", got)
		}
		if !strings.Contains(got, "api-auth") {
			t.Errorf("expected api-auth middleware when BasicAuthLine is set, got:\n%s", got)
		}
	})

	t.Run("certResolver custom", func(t *testing.T) {
		cfg := TraefikDynamicConfig{
			Name:         "svc",
			Domain:       "svc.example.com",
			UpstreamURL:  "http://svc:7000",
			EnableGzip:   false,
			CertResolver: "myresolver",
		}
		got := GenerateTraefikDynamic(cfg)

		if !strings.Contains(got, "certResolver: myresolver") {
			t.Errorf("expected certResolver: myresolver, got:\n%s", got)
		}
	})

	t.Run("certResolver vacio usa letsencrypt por defecto", func(t *testing.T) {
		cfg := TraefikDynamicConfig{
			Name:         "svc",
			Domain:       "svc.example.com",
			UpstreamURL:  "http://svc:7000",
			CertResolver: "",
		}
		got := GenerateTraefikDynamic(cfg)

		if !strings.Contains(got, "certResolver: letsencrypt") {
			t.Errorf("expected certResolver: letsencrypt as default, got:\n%s", got)
		}
	})

	t.Run("snapshot YAML completo replica patron registry_api", func(t *testing.T) {
		cfg := TraefikDynamicConfig{
			Name:          "registry-api",
			Domain:        "registry.organic-machine.com",
			UpstreamURL:   "http://registry-api:8420",
			BasicAuthLine: "PLACEHOLDER_BASICAUTH_LINE",
			EnableGzip:    true,
			CertResolver:  "letsencrypt",
		}
		got := GenerateTraefikDynamic(cfg)

		expected := `http:
  routers:
    registry-api-http:
      rule: "Host(` + "`registry.organic-machine.com`" + `)"
      entryPoints:
        - "http"
      middlewares:
        - "registry-api-redirect"
      service: "registry-api-service"

    registry-api-https:
      rule: "Host(` + "`registry.organic-machine.com`" + `)"
      entryPoints:
        - "https"
      middlewares:
        - "registry-api-auth"
        - "registry-api-gzip"
      service: "registry-api-service"
      tls:
        certResolver: letsencrypt

  services:
    registry-api-service:
      loadBalancer:
        servers:
          - url: "http://registry-api:8420"

  middlewares:
    registry-api-redirect:
      redirectScheme:
        scheme: "https"
    registry-api-auth:
      basicAuth:
        users:
          - "PLACEHOLDER_BASICAUTH_LINE"
    registry-api-gzip:
      compress: true
`
		if got != expected {
			t.Errorf("snapshot mismatch.\nGOT:\n%s\nWANT:\n%s", got, expected)
		}
	})
}
