// Copyright 2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package testutil

import (
	"strings"

	"golang.org/x/net/html"

	"go.pinniped.dev/internal/here"
)

type ChooseIDPPageExpectedValue struct {
	DisplayName string
	URL         string
}

func spaces(howMany int) string {
	return strings.Repeat(" ", howMany)
}

func withNewline(s string) string {
	return s + "\n"
}

func htmlEscapedForHTMLTemplate(s string) string {
	// The HTML templating package also escapes plus characters, which html.EscapeString does not.
	return strings.ReplaceAll(html.EscapeString(s), "+", "&#43;")
}

func ExpectedChooseIDPPageHTML(wantCSS string, wantJS string, wantIDPs []ChooseIDPPageExpectedValue) string {
	top := here.Docf(`
		<!DOCTYPE html>
		<html lang="en">
		<head>
			<title>Choose Identity Provider</title>
			<meta charset="UTF-8">
			<style>%s</style>
			<script>%s</script>
			<link href="data:image/x-icon;base64,[encoded data, 12540 characters]"
				  rel="icon" type="image/x-icon"/>
		</head>
		<body>
		<div class="box" aria-label="choose identity provider form" role="main">
			<div class="form-field">
				<h1>Choose an identity provider to log in</h1>
			</div>
	`, wantCSS, wantJS)

	noscript := withNewline(spaces(4)+`<noscript>`) +
		withNewline(spaces(8)+`<div class="form-field">`) +
		withNewline(spaces(12)+`<ul>`) +
		withNewline(spaces(16))
	for _, wantIDP := range wantIDPs {
		noscript += withNewline(spaces(20)+`<li><a href="`+htmlEscapedForHTMLTemplate(wantIDP.URL)+`">`+htmlEscapedForHTMLTemplate(wantIDP.DisplayName)+`</a></li>`) +
			withNewline(spaces(16))
	}
	noscript += withNewline(spaces(12)+`</ul>`) +
		withNewline(spaces(8)+`</div>`) +
		withNewline(spaces(4)+`</noscript>`)

	buttons := withNewline(spaces(4)+`<div id="choose-idp-form-buttons" hidden>`) +
		withNewline(spaces(8))
	for _, wantIDP := range wantIDPs {
		buttons += withNewline(spaces(12)+`<div class="form-field">`) +
			withNewline(spaces(16)+`<button data-url="`+htmlEscapedForHTMLTemplate(wantIDP.URL)+`"><span>`+htmlEscapedForHTMLTemplate(wantIDP.DisplayName)+`</span></button>`) +
			withNewline(spaces(12)+`</div>`) +
			withNewline(spaces(8))
	}
	buttons += withNewline(spaces(4) + `</div>`)

	bottom := here.Doc(`
		</div>
		</body>
		</html>
	`)

	return top + noscript + buttons + bottom
}
