package main

import (
	"strings"
	"testing"

	"github.com/stretchr/testify/assert"

	httpcontroller "git.vakhrushev.me/av/transcriber/internal/controller/http"
)

// Перечень адресного пространства для проверок журнала. Обработчиков он здесь
// не вешает: журналу нужны только границы, а не то, что стоит за ними.
func journalMounts() []httpcontroller.Mount {
	return []httpcontroller.Mount{
		{Path: httpcontroller.StorageRoot},
		{Path: httpcontroller.PanelRoot},
		{Path: httpcontroller.AppRoot},
		{Path: httpcontroller.AuthRoot},
		{Path: httpcontroller.HealthPath, Exact: true},
		{Path: httpcontroller.MetricsPath, Exact: true},
	}
}

// Имя файла в хранилище в журнал не идёт: оно последняя часть ссылки
// `/api/files/...`, и строка журнала вместе с идентификатором записи собрала бы
// ссылку целиком. Инвариант проекта, critical.
func TestJournalRouteHidesStoredFileName(t *testing.T) {
	cases := []struct {
		name string
		path string
		want string
	}{
		{
			name: "ссылка на файл теряет имя",
			path: "/api/files/files/abc123def456ghi/9f1c-3b2a.mp3",
			want: "/api/files/files/abc123def456ghi/<имя>",
		},
		{
			name: "маршрут остаётся различимым",
			path: "/api/files/files/abc123def456ghi/запись.ogg",
			want: "/api/files/files/abc123def456ghi/<имя>",
		},
		{
			name: "прочие пути не трогаются",
			path: "/app/audiorecords/abc123def456ghi",
			want: "/app/audiorecords/abc123def456ghi",
		},
		{
			name: "приём не трогается",
			path: "/app/audiorecords",
			want: "/app/audiorecords",
		},
		{
			name: "сам префикс без имени не портится",
			path: "/api/files/",
			want: "/api/files/",
		},
	}

	for _, c := range cases {
		t.Run(c.name, func(t *testing.T) {
			assert.Equal(t, c.want, journalRoute(c.path, journalMounts()))
		})
	}
}

// Отдельно и прямо: имени в готовой строке нет. Проверка судит результат, а не
// устройство — переписанная реализация обязана остаться зелёной.
func TestJournalRouteDropsNameEntirely(t *testing.T) {
	const stored = "0f7b8dd3-d1cc-424c.mp3"

	route := journalRoute("/api/files/files/rec0000000000000/"+stored, journalMounts())

	assert.NotContains(t, route, stored, "имя файла в хранилище не доезжает до журнала")
	assert.Contains(t, route, "rec0000000000000", "идентификатор записи остаётся: по нему прослеживается путь")
}

// Путь, не принадлежащий сервису, уходит приложению и в журнал дословно не
// идёт: множеством его значений распоряжается спрашивающий.
func TestJournalRouteHidesWebappPath(t *testing.T) {
	cases := []string{
		"/",
		"/records/abc123def456ghi",
		"/" + strings.Repeat("a", 1024),
	}

	for _, path := range cases {
		route := journalRoute(path, journalMounts())

		assert.Equal(t, webappRoute, route)
	}
}
