package main

import (
	"errors"
	"testing"
	"time"

	"github.com/DATA-DOG/go-sqlmock"
)

func TestWaitReady(t *testing.T) {
	tests := []struct {
		name        string
		timeout     int
		expect      func(mock sqlmock.Sqlmock)
		expectError bool
	}{
		{
			name:    "Successful Connection",
			timeout: 1,
			expect: func(mock sqlmock.Sqlmock) {
				mock.ExpectPing().WillReturnError(nil)
			},
			expectError: false,
		},
		{
			name:    "Successful Connection With Delay",
			timeout: 3,
			expect: func(mock sqlmock.Sqlmock) {
				mock.ExpectPing().WillDelayFor(2 * time.Second).WillReturnError(nil)
			},
			expectError: false,
		},
		{
			name:    "timeout",
			timeout: 1,
			expect: func(mock sqlmock.Sqlmock) {
				mock.ExpectPing().WillDelayFor(2 * time.Second).WillReturnError(nil)
			},
			expectError: true,
		},
		{
			name:    "Access Denied",
			timeout: 1,
			expect: func(mock sqlmock.Sqlmock) {
				mock.ExpectPing().WillReturnError(errors.New("Access denied"))
			},
			expectError: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			db, mock, _ := sqlmock.New(sqlmock.MonitorPingsOption(true))
			defer db.Close()

			tt.expect(mock)

			err := waitReady(db, time.Duration(tt.timeout)*time.Second)

			if (err != nil) != tt.expectError {
				t.Errorf("Expected error status: %v, got: %v", tt.expectError, err != nil)
			}

			if err := mock.ExpectationsWereMet(); err != nil {
				t.Errorf("There were unfulfilled expectations: %s", err)
			}
		})
	}
}
