package migrate

import (
	"errors"
	"testing"

	"github.com/stretchr/testify/require"
	"gorm.io/gorm"
)

func TestNewMigrator(t *testing.T) {
	t.Parallel()

	migrator := NewMigrator()

	require.Equal(t, "migrations", migrator.table)
	require.Empty(t, migrator.records)
	require.NoError(t, migrator.initDB(nil))
}

func TestNewMigratorWithOptions(t *testing.T) {
	t.Parallel()

	expectedErr := errors.New("init failed")
	initDB := func(*gorm.DB) error {
		return expectedErr
	}

	migrator := NewMigrator(
		WithMigratorTable("custom_migrations"),
		WithInitDBFunc(initDB),
	)

	require.Equal(t, "custom_migrations", migrator.table)
	require.ErrorIs(t, migrator.initDB(nil), expectedErr)
}

func TestMigratorAdd(t *testing.T) {
	t.Parallel()

	expectedErr := errors.New("migrate failed")
	migrate := func(*gorm.DB) error {
		return expectedErr
	}
	migrator := NewMigrator()

	require.True(t, migrator.Add("record_202604301400", migrate))

	require.Len(t, migrator.records, 1)
	require.Equal(t, "record_202604301400", migrator.records[0].version)
	require.ErrorIs(t, migrator.records[0].migrate(nil), expectedErr)
}

func TestMigratorAddPanicsOnDuplicateVersion(t *testing.T) {
	t.Parallel()

	migrator := NewMigrator()
	migrator.Add("record_202604301400", nil)

	require.PanicsWithValue(t,
		"migration version is already added: record_202604301400",
		func() {
			migrator.Add("record_202604301400", nil)
		},
	)
}

func TestMigratorSortRecordsByRecordVersion(t *testing.T) {
	t.Parallel()

	migrator := NewMigrator()
	migrator.Add("record_202604301430", nil)
	migrator.Add("record_202604301400", nil)
	migrator.Add("record_202604301405", nil)
	migrator.Add("record_202604291800", nil)

	migrator.sortRecords()

	var versions []string
	for _, record := range migrator.records {
		versions = append(versions, record.version)
	}
	require.Equal(t, []string{
		"record_202604291800",
		"record_202604301400",
		"record_202604301405",
		"record_202604301430",
	}, versions)
}
