package app.mealsmadeeasy.api.job;

import app.mealsmadeeasy.api.PostgresTestsExtension;
import app.mealsmadeeasy.api.recipe.job.RecipeInferJobHandler;
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.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.test.context.bean.override.mockito.MockitoBean;

import java.util.concurrent.TimeUnit;

import static org.awaitility.Awaitility.await;

@SpringBootTest
@ExtendWith(PostgresTestsExtension.class)
public class JobServiceIntegrationTests {

    @Component
    private static final class TestJobHandler implements JobHandler<Object> {

        @Override
        public Class<Object> getPayloadType() {
            return Object.class;
        }

        @Override
        public String getJobKey() {
            return "TEST_JOB_TYPE";
        }

        @Override
        public void handle(Job job, Object payload) {
            // no-op
        }

    }

    @TestConfiguration
    public static class JobServiceIntegrationTestsConfiguration {

        @Bean
        public JobHandler<Object> testJobHandler() {
            return new TestJobHandler();
        }

    }

    // If not mockito, it will try to load a ChatClient
    @MockitoBean
    private RecipeInferJobHandler recipeInferJobHandler;

    @Autowired
    private JobService jobService;

    @Autowired
    private JobRepository jobRepository;

    @Test
    public void smokeScreen() {
        final Job job = this.jobService.create("TEST_JOB_TYPE", null);
        await().atMost(1, TimeUnit.SECONDS).until(() -> {
            final Job foundJob = this.jobRepository.findById(job.getId()).orElse(null);
            if (foundJob == null) {
                return false;
            } else {
                return foundJob.getState().equals(Job.State.DONE);
            }
        });
    }

}
