package drive

import (
	"testing"

	"github.com/ultisuite/ulti-backend/internal/api/apivalidate"
)

func hasFieldDetail(err *apivalidate.ValidationError, field, message string) bool {
	if err == nil {
		return false
	}
	for _, d := range err.Details {
		if d.Field == field && d.Message == message {
			return true
		}
	}
	return false
}

func TestValidateMoveRequest(t *testing.T) {
	if validateMoveRequest(&moveRequest{Source: "/a", Destination: "/b"}) != nil {
		t.Fatal("expected valid move request")
	}
	if err := validateMoveRequest(&moveRequest{Destination: "/b"}); !hasFieldDetail(err, "source", "required") {
		t.Fatal("expected missing source error")
	}
	if err := validateMoveRequest(&moveRequest{Source: "/a"}); !hasFieldDetail(err, "destination", "required") {
		t.Fatal("expected missing destination error")
	}
	if err := validateMoveRequest(&moveRequest{}); len(err.Details) != 2 {
		t.Fatalf("expected two validation errors, got %d", len(err.Details))
	}
}

func TestValidateCopyRequest(t *testing.T) {
	if validateCopyRequest(&copyRequest{Source: "/a", Destination: "/b"}) != nil {
		t.Fatal("expected valid copy request")
	}
	if err := validateCopyRequest(&copyRequest{Destination: "/b"}); !hasFieldDetail(err, "source", "required") {
		t.Fatal("expected missing source error")
	}
	if err := validateCopyRequest(&copyRequest{Source: "/a"}); !hasFieldDetail(err, "destination", "required") {
		t.Fatal("expected missing destination error")
	}
	if err := validateCopyRequest(&copyRequest{}); len(err.Details) != 2 {
		t.Fatalf("expected two validation errors, got %d", len(err.Details))
	}
}

func TestValidateRenameRequest(t *testing.T) {
	if validateRenameRequest(&renameRequest{Path: "/docs", NewName: "report.pdf"}) != nil {
		t.Fatal("expected valid rename request")
	}
	if err := validateRenameRequest(&renameRequest{NewName: "report.pdf"}); !hasFieldDetail(err, "path", "required") {
		t.Fatal("expected missing path error")
	}
	if err := validateRenameRequest(&renameRequest{Path: "/docs"}); !hasFieldDetail(err, "new_name", "required") {
		t.Fatal("expected missing new_name error")
	}
	if err := validateRenameRequest(&renameRequest{Path: "/docs", NewName: "bad/name"}); !hasFieldDetail(err, "new_name", "invalid") {
		t.Fatal("expected invalid new_name error for slash")
	}
}

func TestValidateCreateShareRequest(t *testing.T) {
	if validateCreateShareRequest(&createShareRequest{Path: "/docs/file.pdf"}) != nil {
		t.Fatal("expected valid share request with path only")
	}
	if validateCreateShareRequest(&createShareRequest{Path: "/docs/file.pdf", Role: "editor", Permissions: 0}) != nil {
		t.Fatal("expected role without permissions to be accepted")
	}
	for _, role := range []string{"owner", "editor", "viewer", "Owner", " EDITOR "} {
		if validateCreateShareRequest(&createShareRequest{Path: "/docs/file.pdf", Role: role}) != nil {
			t.Fatalf("expected valid role %q", role)
		}
	}
	if err := validateCreateShareRequest(&createShareRequest{Role: "editor"}); !hasFieldDetail(err, "path", "required") {
		t.Fatal("expected missing path error")
	}
	if err := validateCreateShareRequest(&createShareRequest{Path: "/docs/file.pdf", Role: "admin"}); !hasFieldDetail(err, "role", "invalid") {
		t.Fatal("expected invalid role error")
	}
	if err := validateCreateShareRequest(&createShareRequest{Path: "/docs/file.pdf", Mode: "contact"}); !hasFieldDetail(err, "share_with", "required") {
		t.Fatal("expected missing share_with for contact mode")
	}
	if validateCreateShareRequest(&createShareRequest{Path: "/docs/file.pdf", Mode: "internal"}) != nil {
		t.Fatal("expected valid internal share request")
	}
}

func TestSharePermissionsForRole(t *testing.T) {
	tests := []struct {
		role        string
		permissions int
		ok          bool
	}{
		{role: "owner", permissions: 31, ok: true},
		{role: "editor", permissions: 15, ok: true},
		{role: "viewer", permissions: 1, ok: true},
		{role: "Owner", permissions: 31, ok: true},
		{role: " EDITOR ", permissions: 15, ok: true},
		{role: "admin", permissions: 0, ok: false},
		{role: "", permissions: 0, ok: false},
	}
	for _, tt := range tests {
		got, ok := sharePermissionsForRole(tt.role)
		if ok != tt.ok || got != tt.permissions {
			t.Fatalf("sharePermissionsForRole(%q) = (%d, %v), want (%d, %v)", tt.role, got, ok, tt.permissions, tt.ok)
		}
	}
}
