package rbac

import (
	"reflect"
	"testing"

	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/rbac"
	"code.fbi.h-da.de/danet/gosdn/controller/store"
	"github.com/google/uuid"
)

func TestFileSystemRoleStore_Add(t *testing.T) {
	defer ensureStoreFileForTestsIsRemoved(store.RoleFilename)

	type args struct {
		RoleToAdd rbac.Role
	}
	var AddRole rbac.Role
	tests := []struct {
		name    string
		args    args
		wantErr bool
	}{
		{"AddRole1", args{AddRole}, false},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			s := NewRoleStore()
			if err := s.Add(tt.args.RoleToAdd); (err != nil) != tt.wantErr {
				t.Errorf("FileSystemRoleStore.Add() error = %v, wantErr %v", err, tt.wantErr)
			}
		})
	}
}

func TestFileSystemRoleStore_Delete(t *testing.T) {
	defer ensureStoreFileForTestsIsRemoved(store.RoleFilename)

	type args struct {
		RoleToDelete rbac.Role
	}
	var idtest uuid.UUID
	addRole := NewRole(idtest, "testRole", "role", []string{})
	tests := []struct {
		name    string
		args    args
		wantErr bool
	}{
		{"AddRole1", args{
			addRole,
		}, false},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			s := NewRoleStore()
			if err := s.Add(addRole); err != nil {
				t.Error(err)
			}
			if err := s.Delete(tt.args.RoleToDelete); (err != nil) != tt.wantErr {
				t.Errorf("FileSystemRoleStore.Delete() error = %v, wantErr %v", err, tt.wantErr)
			}
		})
	}
}

func TestFileSystemRoleStore_Get(t *testing.T) {
	defer ensureStoreFileForTestsIsRemoved(store.RoleFilename)

	type args struct {
		query store.Query
	}
	var idtest uuid.UUID
	var arrTest []string
	addRole := NewRole(idtest, "testRole", "role", arrTest)
	tests := []struct {
		name    string
		args    args
		want    rbac.LoadedRole
		wantErr bool
	}{
		{"AddRole1", args{
			store.Query{
				ID: idtest, Name: "test",
			},
		},
			rbac.LoadedRole{ID: idtest.String(), RoleName: "testRole", Description: "role", Permissions: arrTest},
			false},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			s := NewRoleStore()
			if err := s.Add(addRole); err != nil {
				t.Error(err)
			}
			got, err := s.Get(tt.args.query)
			if (err != nil) != tt.wantErr {
				t.Errorf("FileSystemRoleStore.Get() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("FileSystemRoleStore.Get() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestFileSystemRoleStore_GetAll(t *testing.T) {
	defer ensureStoreFileForTestsIsRemoved(store.RoleFilename)

	var idtest uuid.UUID
	var arrTest []string
	addRole1 := NewRole(idtest, "testRole1", "role1", arrTest)
	addRole2 := NewRole(idtest, "testRole2", "role2", arrTest)
	addRole3 := NewRole(idtest, "testRole3", "role3", arrTest)
	tests := []struct {
		name    string
		want    []rbac.LoadedRole
		wantErr bool
	}{
		{
			"testRole",
			[]rbac.LoadedRole{{ID: idtest.String(), RoleName: "testRole1", Description: "role1", Permissions: arrTest}, {ID: idtest.String(), RoleName: "testRole2", Description: "role2", Permissions: arrTest}, {ID: idtest.String(), RoleName: "testRole3", Description: "role3", Permissions: arrTest}},
			false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			var errs []error
			s := NewRoleStore()
			if err := s.Add(addRole1); err != nil {
				errs = append(errs, err)
			}
			if err := s.Add(addRole2); err != nil {
				errs = append(errs, err)
			}
			if err := s.Add(addRole3); err != nil {
				errs = append(errs, err)
			}

			if len(errs) > 0 {
				t.Error(errs)
			}

			got, err := s.GetAll()
			if (err != nil) != tt.wantErr {
				t.Errorf("FileSystemRoleStore.GetAll() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("FileSystemRoleStore.GetAll() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestFileSystemRoleStore_Update(t *testing.T) {
	defer ensureStoreFileForTestsIsRemoved(store.RoleFilename)

	var idtest uuid.UUID
	var arrTest []string
	addRole1 := NewRole(idtest, "testRole1", "role1", arrTest)
	type args struct {
		roleToUpdate rbac.Role
	}
	tests := []struct {
		name    string
		args    args
		wantErr bool
	}{
		{"AddRole1", args{
			addRole1,
		}, false},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			s := NewRoleStore()
			if err := s.Add(addRole1); err != nil {
				t.Error(err)
			}
			if err := s.Update(tt.args.roleToUpdate); (err != nil) != tt.wantErr {
				t.Errorf("FileSystemRoleStore.Update() error = %v, wantErr %v", err, tt.wantErr)
			}
		})
	}
}
