package kr.xit.batch.ens.job;

import org.springframework.batch.core.*;
import org.springframework.batch.core.configuration.annotation.*;
import org.springframework.context.annotation.*;

import kr.xit.batch.ens.task.*;
import kr.xit.biz.ens.service.*;
import kr.xit.core.biz.batch.*;
import kr.xit.core.biz.batch.listener.*;
import kr.xit.core.biz.batch.service.*;
import kr.xit.core.biz.batch.task.*;
import lombok.extern.slf4j.*;

/**
 * <pre>
 * description :
 *
 * packageName : kr.xit.batch.ens.job
 * fileName    : KtGbsAccessTokenUpdateJobConfig
 * author      : seojh
 * date        : 2024-08-29
 * ======================================================================
 * 변경일         변경자        변경 내용
 * ----------------------------------------------------------------------
 * 2024-08-29    julim       최초 생성
 *
 * </pre>
 */
@Slf4j
@Configuration
public class KtGbsAccessTokenUpdateJobConfig {
    private static final String JOB_NAME = "ktGbsAccessTokenUpdateJob";

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    
    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

    private final IBatchCmmService batchCmmService;
    private final IEnsBatchKtGbsAccessTokenUpdateService service;

    public KtGbsAccessTokenUpdateJobConfig(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory,
        IBatchCmmService batchCmmService, IEnsBatchKtGbsAccessTokenUpdateService service) {
        this.jobBuilderFactory = jobBuilderFactory;
        this.stepBuilderFactory = stepBuilderFactory;
        this.batchCmmService = batchCmmService;
        this.service = service;
    }

    @Bean(name = JOB_NAME)
    public Job ktGbsAccessTokenUpdateJob() {
        return jobBuilderFactory.get(JOB_NAME)
                .incrementer(new CustomRunIdIncrementer())
                .listener(new CustomJobListener())
                .listener(new CustomStepListener())
                .listener(new NoWorkFoundStepListener())

                // JOB 시작
                // start() 결과가 FAILED 인경우 종료
                .start(start())
                .on("FAILED")
                .end()

                // start()의 결과로 부터 FAILED를 제외한 모든 경우 to() 실행
                //.from(start())
                .on("*")
                .to(execution())
                .on("FAILED")
                .to(fail())

                .from(execution())
                // to() 실행 결과와 상관 없이 end() 실행
                .on("*")
                .to(end())

                // JOB 종료
                .end()

                .build();
    }

    @Bean(name = JOB_NAME + "_step")
    public Step execution() {
        return stepBuilderFactory.get(JOB_NAME + "_step")
                .tasklet(new KtGbsAccessTokenUpdateTasklet(service))
                .build();
    }

    @JobScope
    @Bean(name = JOB_NAME + "_start_step")
    protected Step start() {
        return stepBuilderFactory.get("Job_Locking")
                .tasklet(new BatchStartTasklet(batchCmmService))
                .build();
    }

    @JobScope
    @Bean(name = JOB_NAME + "_end_step")
    protected Step end() {
        return stepBuilderFactory.get("Lock_Release")
                .tasklet(new BatchEndTasklet(batchCmmService))
                .build();
    }

    @JobScope
    @Bean(name = JOB_NAME + "_fail_step")
    protected Step fail() {
        return stepBuilderFactory.get("Lock_Release")
                .tasklet(new BatchFailEndTasklet(batchCmmService))
                .build();
    }
}
