package headers_test

import (
	"fmt"
	"net/http"
	"reflect"
	"strings"
	"testing"

	"codeberg.org/git-pages/go-headers"
)

func TestExample(t *testing.T) {
	rules := headers.Must(headers.ParseString(`
# enable COOP/COEP on index:
/index.html
  cross-origin-opener-policy: same-origin
  # breaks some use cases
  cross-origin-embedder-policy: credentialless
# on the worker too:
/worker.js
  cross-origin-embedder-policy: credentialless
/*
  x-content-type-options: nosniff
`))
	expected := []headers.Rule{
		{
			Path: "/index.html",
			Headers: http.Header{
				"Cross-Origin-Opener-Policy":   []string{"same-origin"},
				"Cross-Origin-Embedder-Policy": []string{"credentialless"},
			},
		},
		{
			Path: "/worker.js",
			Headers: http.Header{
				"Cross-Origin-Embedder-Policy": []string{"credentialless"},
			},
		},
		{
			Path: "/*",
			Headers: http.Header{
				"X-Content-Type-Options": []string{"nosniff"},
			},
		},
	}
	if !reflect.DeepEqual(rules, expected) {
		t.Fail()
	}
}

func TestErrorLoneHeaderLine(t *testing.T) {
	_, err := headers.ParseString(`
  vary: accept
`)
	if !strings.Contains(fmt.Sprintf("%s", err), "header line without preceding path line") {
		t.Fail()
	}
}

func TestErrorMalformedHeader(t *testing.T) {
	_, err := headers.ParseString(`
/index.html
  malformed
`)
	if !strings.Contains(fmt.Sprintf("%s", err), "header line without separator") {
		t.Fail()
	}
}

func TestMultipleHeaders(t *testing.T) {
	rules := headers.Must(headers.ParseString(`
/index.html
  vary: accept
  vary: x-something
`))
	expected := []headers.Rule{
		{
			Path: "/index.html",
			Headers: http.Header{
				"Vary": []string{"accept", "x-something"},
			},
		},
	}
	if !reflect.DeepEqual(rules, expected) {
		t.Fail()
	}
}

func TestNameNormalization(t *testing.T) {
	rules := headers.Must(headers.ParseString(`
/index.html
  ALLOW: OPTIONS
  allow: GET
`))
	expected := []headers.Rule{
		{
			Path: "/index.html",
			Headers: http.Header{
				"Allow": []string{"OPTIONS", "GET"},
			},
		},
	}
	if !reflect.DeepEqual(rules, expected) {
		t.Fail()
	}
}

func TestSpaceTrimming(t *testing.T) {
	rules := headers.Must(headers.ParseString("/* \n  Access-Control-Allow-Methods: GET"))
	expected := []headers.Rule{
		{
			Path: "/*",
			Headers: http.Header{
				"Access-Control-Allow-Methods": []string{"GET"},
			},
		},
	}
	if !reflect.DeepEqual(rules, expected) {
		t.Fail()
	}
}

func TestUnparse(t *testing.T) {
	rules := headers.Must(headers.ParseString(`
/index.html
  cross-origin-opener-policy: same-origin
/*
  X-CLACKS-OVERHEAD: GNU Terry Pratchett
`))
	unparsed := headers.Must(headers.UnparseString(rules))
	if unparsed != `/index.html
	Cross-Origin-Opener-Policy: same-origin
/*
	X-Clacks-Overhead: GNU Terry Pratchett
` {
		t.Errorf("%v\n", unparsed)
	}
}
