package com.arms.api.admin.indexstatus.model.vo;

import java.util.*;
import java.util.stream.Collectors;

import com.arms.api.admin.indexstatus.model.entity.IndexStatusEntity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@AllArgsConstructor
@Builder
public class IndexStatusesWithJobIdVO {

    @Getter
    private String jobId;

    @Getter
    private String indexAliasName;

    private final Set<String> beforeJobIndexNames = new HashSet<>();

    @Getter
    private Integer beforeIndexCount;

    private final Set<String> afterJobIndexNames = new HashSet<>();

    @Getter
    private Integer afterIndexCount;

    @Getter
    private Date jobStartTime;

    @Getter
    private Date jobEndTime;

    @Getter
    private final List<IndexStatusWithJobIdVO> jobHistories = new ArrayList<>();

    public static IndexStatusesWithJobIdVO from(Map.Entry<String, List<IndexStatusEntity>> listEntry){

        List<IndexStatusEntity> indexStatusEntities = listEntry.getValue();

        Map<String, List<IndexStatusEntity>> indexStatusEntitiesGroupByIndexName
            = indexStatusEntities
                .stream()
                .collect(Collectors.groupingBy(IndexStatusEntity::getIndex));

        IndexStatusesWithJobIdVO indexStatusesWithJobIdVO = IndexStatusesWithJobIdVO.builder()
            .jobId(listEntry.getKey())
            .indexAliasName(listEntry.getValue().stream().findAny().map(IndexStatusEntity::getIndexAlias).orElse(""))
            .build();

        indexStatusEntitiesGroupByIndexName.entrySet()
            .forEach(index -> indexStatusesWithJobIdVO.setIndexStatusesWithJobIdVO(new IndexStatusWithJobIdVO(index)));

        return indexStatusesWithJobIdVO;
    }

    public void setIndexStatusesWithJobIdVO(IndexStatusWithJobIdVO indexStatusWithJobIdVO){
        this.addHistory(indexStatusWithJobIdVO);
        this.setTimestamp(indexStatusWithJobIdVO);
        this.setIndexCount(indexStatusWithJobIdVO);
    }


    private void addHistory(IndexStatusWithJobIdVO indexStatusWithJobIdVO){
        jobHistories.add(indexStatusWithJobIdVO);
    }

    private void setTimestamp(IndexStatusWithJobIdVO indexStatusWithJobIdVO){

        IndexStatusVO beforeIndexStatusVO = indexStatusWithJobIdVO.getBeforeIndexStatusVO();
        IndexStatusVO afterIndexStatusVO = indexStatusWithJobIdVO.getAfterIndexStatusVO();

        if(beforeIndexStatusVO!=null){
            if(jobStartTime==null){
                this.jobStartTime = beforeIndexStatusVO.getTimestamp();
            }

            if(this.jobStartTime.after(beforeIndexStatusVO.getTimestamp())){
                this.jobStartTime = beforeIndexStatusVO.getTimestamp();
            }
        }

        if(afterIndexStatusVO!=null){
            if(jobEndTime==null){
                this.jobEndTime = afterIndexStatusVO.getTimestamp();
            }

            if(this.jobEndTime.before(afterIndexStatusVO.getTimestamp())){
                this.jobEndTime = afterIndexStatusVO.getTimestamp();
            }
        }
    }

    private void setIndexCount(IndexStatusWithJobIdVO indexStatusWithJobIdVO){

        IndexStatusVO beforeIndexStatusVO = indexStatusWithJobIdVO.getBeforeIndexStatusVO();
        IndexStatusVO afterIndexStatusVO = indexStatusWithJobIdVO.getAfterIndexStatusVO();

        if(beforeIndexStatusVO!=null){
            this.beforeJobIndexNames.add(beforeIndexStatusVO.getIndexName());
            this.beforeIndexCount = beforeJobIndexNames.size();
        }

        if(afterIndexStatusVO!=null){
            this.afterJobIndexNames.add(afterIndexStatusVO.getIndexName());
            this.afterIndexCount = afterJobIndexNames.size();
        }
    }
}
