import {URLParser} from "../js/navigation_state_url.mjs"
import {NavigationStateRegistry} from "../js/navigation_state_registry.mjs"
import {NavigationState, NavigationError, navigation_objectify, navigation_deobjectify} from "../js/navigation_state.mjs"
import {assert_equal, assert_not_equal, assert_matches} from "/assert.mjs"

export async function runTests() {
	console.group("NavigationStateRegistry")

	let parser = new URLParser(window.location.origin, window.location.pathname, "b", true, [["pretty", "ugly"]])
	let registry = new NavigationStateRegistry("http://localhost:3003", parser, {})

	console.log("Empty state, equal to base")
	let abort = new AbortController()
	let url = registry.navigation_state_to_url(NavigationState.create())
	assert_equal(0, 1, url.url, window.location.href)
	assert_equal(0, 1, url.is_perfect, true)

	console.log("State with pretty part set")
	abort = new AbortController()
	url = registry.navigation_state_to_url(NavigationState.create({ ugly: "yes" }))
	assert_equal(0, 1, url.url, window.location.origin+window.location.pathname+"/b/pretty/yes")
	assert_equal(0, 1, url.is_perfect, true)

	console.log("State with non-pretty part set")
	abort = new AbortController()
	let state = NavigationState.create({ a: "b" })
	url = registry.navigation_state_to_url(state)
	assert_equal(0, 1, url.url, window.location.origin+window.location.pathname+"/b/a/b")
	assert_equal(0, 1, url.is_perfect, false)
	url = await registry.navigation_state_to_shortened_url(state, abort)
	assert_matches(0, 1, url.url, /^https?:\/\/[^\/]+\/[^\/]+\.html\/b\/[A-Za-z0-9]+\/?$/)
	assert_equal(0, 1, url.is_perfect, true)
	assert_equal(0, 1, url.is_shareable, true)

	registry = new NavigationStateRegistry("http://localhost:3003", parser, {})

	console.log("State with pretty and non-pretty part set")
	abort = new AbortController()
	state = NavigationState.create({ a: "bbbb", ugly: "yes" })
	url = registry.navigation_state_to_url(state)
	assert_equal(0, 1, url.url, window.location.origin+window.location.pathname+"/b/pretty/yes/a/bbbb")
	assert_equal(0, 1, url.is_perfect, false)
	url = await registry.navigation_state_to_shortened_url(state, abort)
	assert_matches(0,1, url.url, /^https?:\/\/[^\/]+\/[^\/]+\.html\/b\/[A-Za-z0-9]+\/pretty\/yes\/?$/)
	let key = url.url.split("/b/")[1].split("/")[0]

	console.log("State key reuse")
	abort = new AbortController()
	state = NavigationState.create({ a: "bbbb", ugly: "no" })
	url = registry.navigation_state_to_url(state)
	assert_equal(0, 1, url.url, window.location.origin+window.location.pathname+`/b/${key}/pretty/no`)
	assert_equal(0, 1, url.is_perfect, true)

	console.log("State too long for url")
	abort = new AbortController()
	state = NavigationState.create({ a: "x".repeat(2000), ugly: "no" })
	url = registry.navigation_state_to_url(state)
	assert_equal(0, 1, url.url, window.location.origin+window.location.pathname+"/==NOT-SHAREABLE")
	assert_equal(0, 1, url.is_perfect, false)
	assert_equal(0, 1, url.is_shareable, false)
	url = await registry.navigation_state_to_shortened_url(state, abort)
	assert_matches(0, 1, url.url, /^https?:\/\/[^\/]+\/[^\/]+\.html\/b\/[A-Za-z0-9]+\/pretty\/no\/?$/)

	console.log("Getting state back from keyed url")
	state = await registry.url_to_navigation_state(window.location.origin + window.location.pathname + `/b/${key}`)
	assert_equal(0, 1, state.url_version, "b")
	assert_equal(0, 1, navigation_objectify(state.navigation_state), navigation_objectify(NavigationState.create({ a: "bbbb" })))
	state = await registry.url_to_navigation_state(window.location.origin+window.location.pathname+`/b/${key}/pretty/no`)
	assert_equal(0, 1, state.url_version, "b")
	assert_equal(0, 1, navigation_objectify(state.navigation_state), navigation_objectify(NavigationState.create({ a: "bbbb", ugly: "no" })))
	state = await registry.url_to_navigation_state(window.location.origin+window.location.pathname+`/b/${key}/pretty/no/a/c`)
	assert_equal(0, 1, state.url_version, "b")
	assert_equal(0, 1, navigation_objectify(state.navigation_state), navigation_objectify(NavigationState.create({ a: "c", ugly: "no" })))
	state = await registry.url_to_navigation_state(window.location.origin+window.location.pathname+`/b/${key}/a/c`)
	assert_equal(0, 1, state.url_version, "b")
	assert_equal(0, 1, navigation_objectify(state.navigation_state), navigation_objectify(NavigationState.create({ a: "c" })))

	console.log("Getting error on attempt to retrieve non-existing state")
	state = await registry.url_to_navigation_state(window.location.origin+window.location.pathname+`/b/this_doesnt_exist`)
	if (!(state.navigation_state instanceof NavigationError)) throw "meh"
	assert_equal(0, 1, state.navigation_state.kind, 'ShortenerRequestFailed')

	console.groupEnd()

	document.getElementById("state_registry_result").innerHTML = "OK"
}
