package system

import (
	"context"
	"errors"
	"testing"
)

type defaultRouterUserRepo struct {
	UserRepo
	hasMenu bool
	err     error
}

type loginUserRepo struct {
	UserRepo
	user *User
	err  error
}

func (r *loginUserRepo) FindUserByUsername(context.Context, string) (*User, error) {
	return r.user, r.err
}

func (r *defaultRouterUserRepo) HasAuthorityMenu(context.Context, uint, string) (bool, error) {
	return r.hasMenu, r.err
}

func TestFallbackDefaultRouterMatchesMenuLookupOutcome(t *testing.T) {
	user := &User{AuthorityID: 888, Authority: Authority{DefaultRouter: "dashboard"}}
	NewUserUsecase(&defaultRouterUserRepo{hasMenu: false}).fallbackDefaultRouter(context.Background(), user)
	if user.Authority.DefaultRouter != "404" {
		t.Fatalf("missing default route = %q", user.Authority.DefaultRouter)
	}

	user.Authority.DefaultRouter = "dashboard"
	NewUserUsecase(&defaultRouterUserRepo{err: errors.New("database unavailable")}).fallbackDefaultRouter(context.Background(), user)
	if user.Authority.DefaultRouter != "dashboard" {
		t.Fatalf("lookup error changed default route to %q", user.Authority.DefaultRouter)
	}

	user.Authority.DefaultRouter = ""
	NewUserUsecase(&defaultRouterUserRepo{}).fallbackDefaultRouter(context.Background(), user)
	if user.Authority.DefaultRouter != "404" {
		t.Fatalf("empty missing default route = %q", user.Authority.DefaultRouter)
	}
}

func TestLoginRejectsMissingUserWithoutPanic(t *testing.T) {
	user, err := NewUserUsecase(&loginUserRepo{}).Login(context.Background(), "missing", "password")
	if !errors.Is(err, ErrInvalidCredentials) || user != nil {
		t.Fatalf("Login() = %#v, %v; want nil, ErrInvalidCredentials", user, err)
	}
}
