package com.spring.infra.batch;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;

/**
 * 배치 작업 정보를 관리하는 서비스 클래스입니다.
 * 
 * <p>이 클래스는 배치 작업의 메타데이터를 저장하고 관리하며,
 * 배치 작업에 대한 CRUD(Create, Read, Update, Delete) 작업을 수행합니다.</p>
 * 
 * <p>배치 작업의 정보는 데이터베이스 또는 메모리에 저장될 수 있으며,
 * 이 서비스를 통해 배치 작업의 상태를 조회하고 업데이트할 수 있습니다.</p>
 * 
 * @author mindol
 * @version 1.0
 */
@Service
@RequiredArgsConstructor
public class BatchJobInfoService {

    /**
     * Spring의 Environment 객체입니다.
     * 
     * <p>환경 설정에서 플레이스홀더를 해석하는 데 사용됩니다.</p>
     */
    private final Environment environment;

    /**
     * 배치 작업 정보를 저장하는 맵입니다.
     * 
     * <p>배치 작업의 이름을 키로 사용하여 BatchJobInfoData 객체를 저장합니다.</p>
     */
    private final Map<String, BatchJobInfoData> batchJobInfoMap = new ConcurrentHashMap<>();

    /**
     * 배치 작업 정보를 설정합니다.
     * 
     * <p>주어진 배치 작업 정보를 맵에 저장합니다.</p>
     * 
     * @param beanName 배치 작업의 이름
     * @param batchJobInfo 배치 작업 정보 객체
     */
    public void setBatchJobInfoData(String beanName, BatchJobInfo batchJobInfo) {
        batchJobInfoMap.put(beanName, processBatchJobInfo(batchJobInfo));
    }

    /**
     * 배치 작업 정보를 조회합니다.
     * 
     * <p>주어진 배치 작업 이름에 해당하는 배치 작업 정보를 반환합니다.</p>
     * 
     * @param beanName 배치 작업의 이름
     * @return 해당 배치 작업 정보 객체, 없으면 null
     */
    public BatchJobInfoData getBatchJobInfo(String beanName) {
        return batchJobInfoMap.get(beanName);
    }

    /**
     * 배치 작업 정보를 처리합니다.
     * 
     * <p>주어진 BatchJobInfo 객체를 기반으로 BatchJobInfoData 객체를 생성합니다.</p>
     * 
     * @param batchJobInfo 배치 작업 정보 객체
     * @return 생성된 BatchJobInfoData 객체
     */
    private BatchJobInfoData processBatchJobInfo(BatchJobInfo batchJobInfo) {
        return new BatchJobInfoData(
            resolvePlaceHolder(batchJobInfo.group()),
            resolvePlaceHolder(batchJobInfo.jobName()),
            resolvePlaceHolder(batchJobInfo.cronExpression()),
            resolvePlaceHolder(batchJobInfo.description())
        );
    }

    /**
     * 주어진 값을 처리하여 플레이스홀더를 해석합니다.
     * 
     * <p>환경 설정에서 플레이스홀더를 해석하여 실제 값을 반환합니다.</p>
     * 
     * @param value 해석할 값
     * @return 해석된 값
     */
    private String resolvePlaceHolder(String value) {
        return environment.resolvePlaceholders(value);
    }
}
