package com.intellij.vcs.log.data;

import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.graph.GraphCommit;
import org.jetbrains.annotations.NotNull;

import java.util.*;

public class VcsLogMultiRepoJoiner<CommitId, Commit extends GraphCommit<CommitId>> {

  @NotNull
  public List<Commit> join(@NotNull Collection<List<Commit>> logsFromRepos) {
    if (logsFromRepos.size() == 1) {
      return logsFromRepos.iterator().next();
    }

    int size = 0;
    for (List<Commit> repo : logsFromRepos) {
      size += repo.size();
    }
    List<Commit> result = new ArrayList<Commit>(size);

    Map<Commit, Iterator<Commit>> nextCommits = ContainerUtil.newHashMap();
    for (List<Commit> log : logsFromRepos) {
      Iterator<Commit> iterator = log.iterator();
      if (iterator.hasNext()) {
        nextCommits.put(iterator.next(), iterator);
      }
    }

    while (!nextCommits.isEmpty()) {
      Commit lastCommit = findLatestCommit(nextCommits.keySet());
      Iterator<Commit> iterator = nextCommits.get(lastCommit);
      result.add(lastCommit);
      nextCommits.remove(lastCommit);

      if (iterator.hasNext()) {
        nextCommits.put(iterator.next(), iterator);
      }
    }

    return result;
  }

  @NotNull
  private Commit findLatestCommit(@NotNull Set<Commit> commits) {
    long maxTimeStamp = Long.MIN_VALUE;
    Commit lastCommit = null;
    for (Commit commit : commits) {
      if (commit.getTimestamp() >= maxTimeStamp) {
        maxTimeStamp = commit.getTimestamp();
        lastCommit = commit;
      }
    }
    assert lastCommit != null;
    return lastCommit;
  }

}
