package storage

import (
	"testing"
	"time"

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

func TestScheduledJobCRUD(t *testing.T) {
	db, err := Open(":memory:")
	require.NoError(t, err)
	defer db.Close()

	// Add a job.
	job := ScheduledJob{
		Name:     "nightly-scan",
		CronExpr: "0 0 * * *",
		ScanPath: "/tmp/repo",
		Enabled:  true,
		Notify:   true,
	}
	id, err := db.SaveScheduledJob(job)
	require.NoError(t, err)
	assert.True(t, id > 0)

	// Get the job by ID.
	got, err := db.GetScheduledJob(id)
	require.NoError(t, err)
	assert.Equal(t, "nightly-scan", got.Name)
	assert.Equal(t, "0 0 * * *", got.CronExpr)
	assert.Equal(t, "/tmp/repo", got.ScanPath)
	assert.True(t, got.Enabled)
	assert.True(t, got.Notify)
	assert.Nil(t, got.LastRunAt)

	// List all jobs.
	jobs, err := db.ListScheduledJobs()
	require.NoError(t, err)
	assert.Len(t, jobs, 1)
	assert.Equal(t, "nightly-scan", jobs[0].Name)

	// Add a second job (disabled).
	job2 := ScheduledJob{
		Name:     "weekly-scan",
		CronExpr: "0 0 * * 0",
		ScanPath: "/tmp/other",
		Enabled:  false,
		Notify:   false,
	}
	id2, err := db.SaveScheduledJob(job2)
	require.NoError(t, err)

	// List enabled only.
	enabled, err := db.ListEnabledScheduledJobs()
	require.NoError(t, err)
	assert.Len(t, enabled, 1)
	assert.Equal(t, id, enabled[0].ID)

	// Delete the first job.
	affected, err := db.DeleteScheduledJob(id)
	require.NoError(t, err)
	assert.Equal(t, int64(1), affected)

	// Only the second job should remain.
	jobs, err = db.ListScheduledJobs()
	require.NoError(t, err)
	assert.Len(t, jobs, 1)
	assert.Equal(t, id2, jobs[0].ID)

	// Delete non-existent returns 0 affected.
	affected, err = db.DeleteScheduledJob(999)
	require.NoError(t, err)
	assert.Equal(t, int64(0), affected)
}

func TestUpdateJobLastRun(t *testing.T) {
	db, err := Open(":memory:")
	require.NoError(t, err)
	defer db.Close()

	id, err := db.SaveScheduledJob(ScheduledJob{
		Name:     "test",
		CronExpr: "*/5 * * * *",
		ScanPath: "/tmp/test",
		Enabled:  true,
		Notify:   true,
	})
	require.NoError(t, err)

	job, err := db.GetScheduledJob(id)
	require.NoError(t, err)
	assert.Nil(t, job.LastRunAt)

	// Update last run.
	now := time.Now().Truncate(time.Second)
	require.NoError(t, db.UpdateJobLastRun(id, now))

	job, err = db.GetScheduledJob(id)
	require.NoError(t, err)
	require.NotNil(t, job.LastRunAt, "LastRunAt should be set after UpdateJobLastRun")
	assert.Equal(t, now.Format("2006-01-02 15:04:05"), job.LastRunAt.Format("2006-01-02 15:04:05"))
}
