package com.lanyuanxiaoyao.service.hudi.service;

import com.eshore.odcp.hudi.connector.entity.TableMeta;
import com.lanyuanxiaoyao.service.configuration.entity.hudi.HudiInstant;
import com.lanyuanxiaoyao.service.forest.service.InfoService;
import com.lanyuanxiaoyao.service.hudi.utils.HoodieUtils;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hudi.common.table.HoodieTableMetaClient;
import org.apache.hudi.common.table.timeline.HoodieInstant;
import org.eclipse.collections.api.list.ImmutableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

/**
 * 时间线查询
 *
 * @author lanayuanxiaoyao
 * @date 2023-05-01
 */
@Service
public class TimelineService {
    private static final Logger logger = LoggerFactory.getLogger(TimelineService.class);

    private final InfoService infoService;

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    public TimelineService(InfoService infoService) {
        this.infoService = infoService;
    }

    @Cacheable(value = "timeline", sync = true, key = "#flinkJobId.toString()+#alias")
    @Retryable(Throwable.class)
    public ImmutableList<HudiInstant> timeline(Long flinkJobId, String alias) throws IOException {
        TableMeta meta = infoService.tableMetaDetail(flinkJobId, alias);
        return timeline(meta.getHudi().getTargetHdfsPath());
    }

    @Cacheable(value = "timeline", sync = true, key = "#hdfs")
    @Retryable(Throwable.class)
    public ImmutableList<HudiInstant> timeline(String hdfs) throws IOException {
        HoodieTableMetaClient client = HoodieTableMetaClient.builder()
                .setConf(new Configuration())
                .setBasePath(hdfs)
                .build();
        ImmutableList<HudiInstant> activeInstants = HoodieUtils.getAllInstants(client, HoodieTableMetaClient::getActiveTimeline)
                .collect(instant -> covert("active", instant));
        ImmutableList<HudiInstant> archiveInstants = HoodieUtils.getAllInstants(client, HoodieTableMetaClient::getArchivedTimeline)
                .collect(instant -> covert("archive", instant));
        return activeInstants.newWithAll(archiveInstants)
                .toSortedList(HudiInstant::compareTo)
                .toImmutable();
    }

    private HudiInstant covert(String type, HoodieInstant instant) {
        return new HudiInstant(
                instant.getAction(),
                instant.getState().name(),
                instant.getTimestamp(),
                instant.getFileName(),
                type
        );
    }
}
