package service

import (
	"errors"
	"fmt"
	"testing"

	"github.com/stretchr/testify/assert"
)

type stubSQLErrorLogger struct {
	messages []string
}

func (l *stubSQLErrorLogger) Errorf(template string, args ...any) {
	l.messages = append(l.messages, fmt.Sprintf(template, args...))
}

type stubSafeLoggableSQLError struct {
	message string
	cause   string
}

func (e stubSafeLoggableSQLError) Error() string {
	return e.message
}

func (e stubSafeLoggableSQLError) CauseForLog() string {
	return e.cause
}

func Test_logSQLError(t *testing.T) {
	tests := []struct {
		name       string
		err        error
		wantMsg    string
		wantLogged string
	}{
		{
			name:       "plain error logs sanitized dsn message",
			err:        errors.New("boom root:secret@tcp(tidb:4000)/mysql"),
			wantMsg:    "failed to reset the root password: boom root:****@tcp(tidb:4000)/mysql",
			wantLogged: "failed to reset the root password: boom root:****@tcp(tidb:4000)/mysql",
		},
		{
			name:       "plain error redacts identified by literal in message and log",
			err:        errors.New("driver returned ALTER USER 'root'@'%' IDENTIFIED BY 'secret''suffix'"),
			wantMsg:    "failed to reset the root password: driver returned ALTER USER 'root'@'%' IDENTIFIED BY '****'",
			wantLogged: "failed to reset the root password: driver returned ALTER USER 'root'@'%' IDENTIFIED BY '****'",
		},
		{
			name: "safe loggable error logs sanitized cause",
			err: stubSafeLoggableSQLError{
				message: "exec ResetRootPassword failed",
				cause:   "driver returned sanitized detail",
			},
			wantMsg:    "failed to reset the root password: driver returned sanitized detail",
			wantLogged: "failed to reset the root password: driver returned sanitized detail",
		},
		{
			name: "safe loggable error re-sanitizes partially redacted cause",
			err: stubSafeLoggableSQLError{
				message: "exec ResetRootPassword failed",
				cause:   "driver returned ALTER USER 'root' IDENTIFIED BY '****''ss'",
			},
			wantMsg:    "failed to reset the root password: driver returned ALTER USER 'root' IDENTIFIED BY '****'",
			wantLogged: "failed to reset the root password: driver returned ALTER USER 'root' IDENTIFIED BY '****'",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			logger := &stubSQLErrorLogger{}

			msg := logSQLError(logger, "failed to reset the root password", tt.err)

			assert.Equal(t, tt.wantMsg, msg)
			assert.Equal(t, []string{tt.wantLogged}, logger.messages)
		})
	}
}
