package automation

import (
	"context"
	"errors"
	"testing"
	"time"

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

func TestAutomationLogChunkMetadataIsIdempotentBySequence(t *testing.T) {
	ctx := context.Background()
	store := newAutomationStoreForTest(t)
	now := time.Date(2026, 6, 5, 12, 0, 0, 0, time.UTC)
	job := createLeasedAutomationBlobJob(t, ctx, store, "ws-1", "run-1", "job-1", "lease-1", now)
	chunk := AutomationLogChunk{ID: "chunk-1", WorkspaceID: "ws-1", RunID: "run-1", JobRunID: "job-1", Stream: "stdout", Sequence: 1, ObjectKey: "workspaces/ws-1/runs/run-1/jobs/job-1/logs/stdout/1.log", SizeBytes: 5, SHA256: "hash-1", ContentType: "text/plain", CreatedAt: now}
	event := AutomationEvent{ID: "event-log-1", WorkspaceID: "ws-1", RunID: "run-1", JobRunID: "job-1", EventType: "job_log_appended", MetadataJSON: "{}", CreatedAt: now}

	created, createdEvent, err := store.CreateLeasedJobLogChunk(ctx, job.ID, "lease-1", chunk, event, now)
	require.NoError(t, err)
	require.Equal(t, chunk.ID, created.ID)
	require.Equal(t, event.ID, createdEvent.ID)

	retried, retriedEvent, err := store.CreateLeasedJobLogChunk(ctx, job.ID, "lease-1", chunk, event, now.Add(time.Second))
	require.NoError(t, err)
	require.Equal(t, chunk.ID, retried.ID)
	require.Equal(t, event.ID, retriedEvent.ID)

	var chunks int64
	require.NoError(t, store.db.Model(&AutomationLogChunk{}).Count(&chunks).Error)
	require.EqualValues(t, 1, chunks)
	var events int64
	require.NoError(t, store.db.Model(&AutomationEvent{}).Count(&events).Error)
	require.EqualValues(t, 1, events)

	chunk.SHA256 = "hash-2"
	_, _, err = store.CreateLeasedJobLogChunk(ctx, job.ID, "lease-1", chunk, event, now.Add(2*time.Second))
	require.ErrorIs(t, err, ErrAutomationBlobMetadataConflict)
}

func TestAutomationArtifactMetadataIsWorkspaceAndRunScoped(t *testing.T) {
	ctx := context.Background()
	store := newAutomationStoreForTest(t)
	now := time.Date(2026, 6, 5, 12, 15, 0, 0, time.UTC)
	job := createLeasedAutomationBlobJob(t, ctx, store, "ws-1", "run-1", "job-1", "lease-1", now)
	artifact := AutomationArtifact{ID: "artifact-1", WorkspaceID: "ws-1", RunID: "run-1", JobRunID: "job-1", Name: "build.txt", ObjectKey: "workspaces/ws-1/runs/run-1/jobs/job-1/artifacts/artifact-1/build.txt", SizeBytes: 5, SHA256: "hash-1", ContentType: "text/plain", CreatedAt: now, UpdatedAt: now}
	event := AutomationEvent{ID: "event-artifact-1", WorkspaceID: "ws-1", RunID: "run-1", JobRunID: "job-1", EventType: "job_artifact_recorded", MetadataJSON: "{}", CreatedAt: now}

	created, _, err := store.CreateLeasedJobArtifact(ctx, job.ID, "lease-1", artifact, event, now)
	require.NoError(t, err)
	require.Equal(t, artifact.ID, created.ID)

	loaded, err := store.GetArtifact(ctx, "ws-1", "run-1", "artifact-1")
	require.NoError(t, err)
	require.Equal(t, "build.txt", loaded.Name)
	_, err = store.GetArtifact(ctx, "ws-2", "run-1", "artifact-1")
	require.True(t, errors.Is(err, gorm.ErrRecordNotFound))
	_, err = store.GetArtifact(ctx, "ws-1", "run-2", "artifact-1")
	require.True(t, errors.Is(err, gorm.ErrRecordNotFound))
}

func createLeasedAutomationBlobJob(t *testing.T, ctx context.Context, store *Store, workspaceID string, runID string, jobRunID string, leaseOwner string, now time.Time) AutomationJob {
	t.Helper()
	return createLeasedAutomationJob(t, ctx, store, workspaceID, runID, jobRunID, leaseOwner, now, now.Add(time.Hour))
}
