package ical

import (
	"htwkalender/ical/model"
	"net/url"
	"reflect"
	"testing"
)

func Test_buildDataURL(t *testing.T) {
	type args struct {
		data string
	}
	tests := []struct {
		name string
		args args
		want *url.URL
	}{
		{
			name: "Test 1",
			args: args{
				data: "text/calendar;charset=utf-8;base64,ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg",
			},
			want: &url.URL{
				Scheme: "data",
				Opaque: "text/calendar;charset=utf-8;base64,ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg",
			},
		},
		{
			name: "Test 2",
			args: args{
				data: "text/calendar;charset=utf-8;base64,ÄÜ'*A`+#Add\"$%&/()=?",
			},
			want: &url.URL{
				Scheme: "data",
				Opaque: "text/calendar;charset=utf-8;base64,ÄÜ'*A`+#Add\"$%&/()=?",
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := buildDataURL(tt.args.data); !reflect.DeepEqual(got, tt.want) {
				t.Errorf("buildDataURL() = %v, want %v", got, tt.want)
			}
		})
	}
}

func Test_identifyUserAgent(t *testing.T) {
	type args struct {
		userAgent string
	}
	tests := []struct {
		name string
		args args
		want string
	}{
		{
			name: "Test 1",
			args: args{
				userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.10.0",
			},
			want: "Thunderbird",
		},
		{
			name: "Test 2",
			args: args{
				userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 GoogleCalendar/78.10.0",
			},
			want: "",
		},
		{
			name: "Test 3",
			args: args{
				userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101",
			},
			want: "",
		},
		{
			name: "Test 4",
			args: args{
				userAgent: "Google-Calendar-Importer 1.0",
			},
			want: "Google-Calendar-Importer",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := identifyUserAgent(tt.args.userAgent); got != tt.want {
				t.Errorf("identifyUserAgent() = %v, want %v", got, tt.want)
			}
		})
	}
}

func Test_buildPlainTextDescription(t *testing.T) {
	type args struct {
		event model.Event
	}
	tests := []struct {
		name string
		args args
		want string
	}{
		{
			name: "All fields have valid values",
			args: args{
				event: model.Event{
					Prof:       "Dr. Smith",
					Course:     "Math 101",
					EventType:  "S",
					Compulsory: "w",
					Notes:      "Bring textbook",
				},
			},
			want: "Profs: Dr. Smith\nGruppen: Math 101\nTyp: Sw\nNotizen: Bring textbook\n",
		},
		{
			name: "All fields are empty",
			args: args{
				event: model.Event{
					Prof:       "",
					Course:     "",
					EventType:  "",
					Compulsory: "",
					Notes:      "",
				},
			},
			want: "",
		},
		{
			name: "Some fields are empty",
			args: args{
				event: model.Event{
					Prof:       "Dr. Smith",
					Course:     "",
					EventType:  "Seminar",
					Compulsory: "",
					Notes:      "",
				},
			},
			want: "Profs: Dr. Smith\nTyp: Seminar\n",
		},
		{
			name: "Fields contain only whitespace",
			args: args{
				event: model.Event{
					Prof:       "   ",
					Course:     "   ",
					EventType:  "   ",
					Compulsory: "",
					Notes:      "   ",
				},
			},
			want: "",
		},
		{
			name: "Mix of valid values, empty values, and whitespace",
			args: args{
				event: model.Event{
					Prof:       "Dr. Brown",
					Course:     "   ",
					EventType:  "V",
					Compulsory: "p",
					Notes:      "",
				},
			},
			want: "Profs: Dr. Brown\nTyp: Vp\n",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := buildPlainTextDescription(tt.args.event); got != tt.want {
				t.Errorf("buildPlainTextDescription() = %v, want %v", got, tt.want)
			}
		})
	}
}

func Test_generateRoomLinksForGoogleCalendar(t *testing.T) {
	type args struct {
		rooms string
	}
	tests := []struct {
		name string
		args args
		want string
	}{
		{
			name: "Test 1",
			args: args{
				rooms: "A123, ZU423, C789",
			},
			want: "Orte: <a href=\"https://map.htwk-leipzig.de/room/A123\"> A123 </a> <a href=\"https://map.htwk-leipzig.de/room/ZU423\"> ZU423 </a> <a href=\"https://map.htwk-leipzig.de/room/C789\"> C789 </a> ",
		},
		{
			name: "Test 2",
			args: args{
				rooms: "A123",
			},
			want: "Orte: <a href=\"https://map.htwk-leipzig.de/room/A123\"> A123 </a> ",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := generateRoomLinksForGoogleCalendar(tt.args.rooms); got != tt.want {
				t.Errorf("generateRoomLinksForGoogleCalendar() = %v, want %v", got, tt.want)
			}
		})
	}
}

func Test_generateHTMLDescriptionForThunderbird(t *testing.T) {
	type args struct {
		event model.Event
	}
	tests := []struct {
		name string
		args args
		want string
	}{
		{
			name: "All fields have valid values including rooms",
			args: args{
				event: model.Event{
					Prof:       "Dr. Smith",
					Course:     "Math 101",
					EventType:  "Lecture",
					Compulsory: " (mandatory)",
					Rooms:      "ZU423, FE231",
				},
			},
			want: "Profs: Dr. Smith<br>Gruppen: Math 101<br>Typ: Lecture (mandatory)<br>Orte: <a href=\"https://map.htwk-leipzig.de/room/ZU423\">ZU423</a> <a href=\"https://map.htwk-leipzig.de/room/FE231\">FE231</a> ",
		},
		{
			name: "All fields are empty",
			args: args{
				event: model.Event{
					Prof:       "",
					Course:     "",
					EventType:  "",
					Compulsory: "",
					Rooms:      "",
				},
			},
			want: "",
		},
		{
			name: "Some fields are empty, rooms have valid values",
			args: args{
				event: model.Event{
					Prof:       "Dr. Smith",
					Course:     "",
					EventType:  "Seminar",
					Compulsory: "",
					Rooms:      "TR_L1.06-B",
				},
			},
			want: "Profs: Dr. Smith<br>Typ: Seminar<br>Orte: <a href=\"https://map.htwk-leipzig.de/room/TR_L106\">TR_L1.06-B</a> ",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := generateHTMLDescriptionForThunderbird(tt.args.event); got != tt.want {
				t.Errorf("generateHTMLDescriptionForThunderbird() = %v, want %v", got, tt.want)
			}
		})
	}
}

func Test_generateDescription(t *testing.T) {
	type args struct {
		event     model.Event
		userAgent string
	}
	tests := []struct {
		name        string
		args        args
		description string
		altrep      string
	}{
		{
			name: "Test 1",
			args: args{
				event: model.Event{
					Prof:       "Dr. Smith",
					Course:     "Math 101",
					EventType:  "Lecture",
					Compulsory: " (mandatory)",
					Rooms:      "ZU423, FE231",
				},
				userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.10.0",
			},
			description: "Profs: Dr. Smith\nGruppen: Math 101\nTyp: Lecture (mandatory)\n",
			altrep:      "text/html,Profs:%20Dr.%20Smith%3Cbr%3EGruppen:%20Math%20101%3Cbr%3ETyp:%20Lecture%20%28mandatory%29%3Cbr%3EOrte:%20%3Ca%20href=%22https:%2F%2Fmap.htwk-leipzig.de%2Froom%2FZU423%22%3EZU423%3C%2Fa%3E%20%3Ca%20href=%22https:%2F%2Fmap.htwk-leipzig.de%2Froom%2FFE231%22%3EFE231%3C%2Fa%3E%20",
		},
		{
			name: "Test 2",
			args: args{
				event: model.Event{
					Prof:       "Dr. Smith",
					Course:     "Math 101",
					EventType:  "Lecture",
					Compulsory: " (mandatory)",
					Rooms:      "ZU423, FE231",
				},
				userAgent: "Google-Calendar-Importer",
			},
			description: "Profs: Dr. Smith\nGruppen: Math 101\nTyp: Lecture (mandatory)\nOrte: <a href=\"https://map.htwk-leipzig.de/room/ZU423\"> ZU423 </a> <a href=\"https://map.htwk-leipzig.de/room/FE231\"> FE231 </a> ",
			altrep:      "",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, got1 := generateDescription(tt.args.event, tt.args.userAgent)
			if got != tt.description {
				t.Errorf("generateDescription() got = %v, want %v", got, tt.description)
			}
			if got1 != tt.altrep {
				t.Errorf("generateDescription() got1 = %v, want %v", got1, tt.altrep)
			}
		})
	}
}
