/*
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package com.runicgateway.app.core.net

import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test

/** Unit tests for the first-run base-URL normalization (PLAN.md §3). */
class ServerUrlTest {

    private fun valid(raw: String, allowInsecure: Boolean = true) =
        (ServerUrl.normalize(raw, allowInsecure) as ServerUrl.Result.Valid).url

    private fun invalid(raw: String, allowInsecure: Boolean = true) =
        (ServerUrl.normalize(raw, allowInsecure) as ServerUrl.Result.Invalid).reason

    @Test fun blankIsRejected() {
        assertEquals(ServerUrl.Reason.BLANK, invalid(""))
        assertEquals(ServerUrl.Reason.BLANK, invalid("   "))
    }

    @Test fun nonHttpSchemeIsRejected() {
        assertEquals(ServerUrl.Reason.UNSUPPORTED_SCHEME, invalid("ftp://example.com"))
        assertEquals(ServerUrl.Reason.UNSUPPORTED_SCHEME, invalid("ws://example.com"))
    }

    @Test fun garbageIsMalformed() {
        assertEquals(ServerUrl.Reason.MALFORMED, invalid("has spaces in it"))
    }

    @Test fun httpRejectedWhenInsecureDisallowed() {
        assertEquals(ServerUrl.Reason.INSECURE, invalid("http://example.com", allowInsecure = false))
    }

    @Test fun httpAllowedInDebug() {
        val url = valid("http://127.0.0.1:3000", allowInsecure = true)
        assertEquals("http", url.scheme)
        assertEquals(3000, url.port)
    }

    @Test fun schemelessInputGetsHttps() {
        val url = valid("shard.example.com", allowInsecure = false)
        assertEquals("https", url.scheme)
        assertEquals("shard.example.com", url.host)
        assertEquals("/", url.encodedPath)
    }

    @Test fun trailingSlashIsEnforced() {
        assertTrue(valid("https://example.com").toString().endsWith("/"))
        assertEquals("/base/", valid("https://example.com/base").encodedPath)
        assertEquals("/base/", valid("https://example.com/base/").encodedPath)
    }

    @Test fun queryAndFragmentAreStripped() {
        val url = valid("https://example.com/base?token=abc#frag")
        assertEquals("/base/", url.encodedPath)
        assertNull(url.query)
        assertEquals("https://example.com/base/", url.toString())
    }
}
