package app.mealsmadeeasy.api.recipe.job;

import app.mealsmadeeasy.api.MinIOTestsExtension;
import app.mealsmadeeasy.api.PostgresTestsExtension;
import app.mealsmadeeasy.api.file.File;
import app.mealsmadeeasy.api.file.FileService;
import app.mealsmadeeasy.api.recipe.RecipeDraft;
import app.mealsmadeeasy.api.recipe.RecipeService;
import app.mealsmadeeasy.api.user.User;
import app.mealsmadeeasy.api.user.UserCreateException;
import app.mealsmadeeasy.api.user.UserService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.testcontainers.junit.jupiter.Testcontainers;

import java.io.IOException;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static org.awaitility.Awaitility.await;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;

@SpringBootTest
@ExtendWith({ PostgresTestsExtension.class, MinIOTestsExtension.class })
@Testcontainers
public class RecipeInferJobAiIntegrationTests {

    @Autowired
    private UserService userService;

    @Autowired
    private RecipeService recipeService;

    @Autowired
    private FileService fileService;

    @Test
    public void enqueueJobAndWait() throws UserCreateException, IOException {
        final String ownerName = UUID.randomUUID().toString();
        final User owner = this.userService.createUser(
                ownerName,
                ownerName + "@test.com",
                "test-pass"
        );
        final File sourceFile = this.fileService.create(
                this.getClass().getResourceAsStream("/recipe.jpeg"),
                "recipe.jpeg",
                127673L,
                owner
        );
        final RecipeDraft draft = this.recipeService.createAiDraft(sourceFile, owner);

        await().atMost(60, TimeUnit.SECONDS).until(() -> {
            final RecipeDraft foundDraft = this.recipeService.getDraftById(draft.getId());
            return foundDraft.getState().equals(RecipeDraft.State.ENTER_DATA);
        });

        final RecipeDraft draftWithInference = this.recipeService.getDraftById(draft.getId());

        assertThat(draftWithInference.getTitle(), is(notNullValue()));
        assertThat(draftWithInference.getIngredients(), is(notNullValue()));

        assertThat(draftWithInference.getInferences(), is(notNullValue()));
        final List<RecipeDraft.RecipeDraftInference> inferences = draftWithInference.getInferences();

        assertThat(inferences.size(), is(1));
        final RecipeDraft.RecipeDraftInference inference = inferences.getFirst();
        assertThat(inference.getTitle(), is(notNullValue()));
        assertThat(inference.getRawText(), is(notNullValue()));
        assertThat(inference.getInferredAt(), is(notNullValue()));
    }

}
