// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

package lunatask_test

import (
	"errors"
	"testing"

	lunatask "git.secluded.site/go-lunatask"
)

func TestParseDeepLink(t *testing.T) {
	t.Parallel()

	tests := []struct {
		name         string
		input        string
		wantResource lunatask.Resource
		wantUUID     string
		wantErr      error
	}{
		// Valid deep links
		{"task_link", "lunatask://tasks/abc-123", lunatask.ResourceTask, "abc-123", nil},
		{"area_link", "lunatask://areas/def-456", lunatask.ResourceArea, "def-456", nil},
		{"goal_link", "lunatask://goals/ghi-789", lunatask.ResourceGoal, "ghi-789", nil},
		{"note_link", "lunatask://notes/jkl-012", lunatask.ResourceNote, "jkl-012", nil},
		{"person_link", "lunatask://people/mno-345", lunatask.ResourcePerson, "mno-345", nil},
		{"notebook_link", "lunatask://notebooks/pqr-678", lunatask.ResourceNotebook, "pqr-678", nil},

		// Plain UUIDs
		{"plain_uuid", "abc-123-def-456", "", "abc-123-def-456", nil},
		{"uuid_only", "12345678-1234-1234-1234-123456789012", "", "12345678-1234-1234-1234-123456789012", nil},

		// Invalid inputs
		{"empty", "", "", "", lunatask.ErrInvalidDeepLink},
		{"invalid_resource", "lunatask://invalid/abc-123", "", "", lunatask.ErrInvalidResource},
		{"missing_uuid", "lunatask://tasks/", "", "", lunatask.ErrInvalidDeepLink},
		{"missing_resource", "lunatask:///abc-123", "", "", lunatask.ErrInvalidDeepLink},
		{"malformed", "lunatask://tasks", "", "", lunatask.ErrInvalidDeepLink},
	}

	for _, testCase := range tests {
		t.Run(testCase.name, func(t *testing.T) {
			t.Parallel()

			resource, uuid, err := lunatask.ParseDeepLink(testCase.input)

			if testCase.wantErr != nil {
				if !errors.Is(err, testCase.wantErr) {
					t.Errorf("ParseDeepLink(%q) error = %v, want %v", testCase.input, err, testCase.wantErr)
				}

				return
			}

			if err != nil {
				t.Errorf("ParseDeepLink(%q) unexpected error = %v", testCase.input, err)

				return
			}

			if resource != testCase.wantResource {
				t.Errorf("ParseDeepLink(%q) resource = %q, want %q", testCase.input, resource, testCase.wantResource)
			}

			if uuid != testCase.wantUUID {
				t.Errorf("ParseDeepLink(%q) uuid = %q, want %q", testCase.input, uuid, testCase.wantUUID)
			}
		})
	}
}

func TestBuildDeepLink(t *testing.T) {
	t.Parallel()

	tests := []struct {
		name     string
		resource lunatask.Resource
		id       string
		want     string
		wantErr  error
	}{
		// Valid builds
		{"task", lunatask.ResourceTask, "abc-123", "lunatask://tasks/abc-123", nil},
		{"area", lunatask.ResourceArea, "def-456", "lunatask://areas/def-456", nil},
		{"goal", lunatask.ResourceGoal, "ghi-789", "lunatask://goals/ghi-789", nil},
		{"note", lunatask.ResourceNote, "jkl-012", "lunatask://notes/jkl-012", nil},
		{"person", lunatask.ResourcePerson, "mno-345", "lunatask://people/mno-345", nil},
		{"notebook", lunatask.ResourceNotebook, "pqr-678", "lunatask://notebooks/pqr-678", nil},

		// Invalid inputs
		{"empty_id", lunatask.ResourceTask, "", "", lunatask.ErrInvalidUUID},
		{"invalid_resource", lunatask.Resource("invalid"), "abc-123", "", lunatask.ErrInvalidResource},
	}

	for _, testCase := range tests {
		t.Run(testCase.name, func(t *testing.T) {
			t.Parallel()

			got, err := lunatask.BuildDeepLink(testCase.resource, testCase.id)

			if testCase.wantErr != nil {
				if !errors.Is(err, testCase.wantErr) {
					t.Errorf("BuildDeepLink(%q, %q) error = %v, want %v", testCase.resource, testCase.id, err, testCase.wantErr)
				}

				return
			}

			if err != nil {
				t.Errorf("BuildDeepLink(%q, %q) unexpected error = %v", testCase.resource, testCase.id, err)

				return
			}

			if got != testCase.want {
				t.Errorf("BuildDeepLink(%q, %q) = %q, want %q", testCase.resource, testCase.id, got, testCase.want)
			}
		})
	}
}
