package migrations

import (
	"context"
	"testing"

	"github.com/DATA-DOG/go-sqlmock"
	"github.com/stretchr/testify/require"
)

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

	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
	require.NoError(t, err)
	defer db.Close()

	mock.ExpectExec("CREATE TABLE demo (id INT);").WillReturnResult(sqlmock.NewResult(0, 0))
	mock.ExpectExec("INSERT INTO demo VALUES (1);").WillReturnResult(sqlmock.NewResult(0, 1))

	err = ExecSQLStatements(context.Background(), db, `
CREATE TABLE demo (id INT);

INSERT INTO demo VALUES (1);
`)
	require.NoError(t, err)
	require.NoError(t, mock.ExpectationsWereMet())
}

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

	require.ErrorContains(t, ExecSQLStatements(context.Background(), nil, "SELECT 1;"), "sql db is nil")
}

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

	report := ApplyReport{
		Database:             "tidb",
		SchemaAlreadyCurrent: true,
		Before:               VersionState{Known: true, Current: 3, Target: 4, Pending: true},
		After:                VersionState{Known: true, Current: 4, Target: 4, Pending: false},
		ExecutedFiles:        []ExecutedFile{{Path: "004_add_table.sql", Version: 4}},
		Notes:                []string{"applied"},
	}
	require.True(t, report.SchemaAlreadyCurrent)
	require.True(t, report.Before.Pending)
	require.False(t, report.After.Pending)
	require.Equal(t, int64(4), report.ExecutedFiles[0].Version)
	require.Equal(t, "applied", report.Notes[0])
}
