package zielu.gittoolbox.ui.statusBar;
import com.intellij.openapi.project.Project;
import com.intellij.util.containers.hash.LinkedHashMap;
import com.intellij.util.text.DateFormatUtil;
import git4idea.GitUtil;
import git4idea.repo.GitRepository;
import git4idea.util.GitUIUtil;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import jodd.util.StringBand;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import zielu.gittoolbox.GitToolBoxConfigForProject;
import zielu.gittoolbox.GitToolBoxProject;
import zielu.gittoolbox.ResBundle;
import zielu.gittoolbox.cache.PerRepoInfoCache;
import zielu.gittoolbox.cache.RepoInfo;
import zielu.gittoolbox.fetch.AutoFetch;
import zielu.gittoolbox.status.GitAheadBehindCount;
import zielu.gittoolbox.ui.StatusText;
import zielu.gittoolbox.util.GtUtil;
import zielu.gittoolbox.util.Html;
public class StatusToolTip {
private final Project myProject;
private GitRepository myCurrentRepository;
private String myCurrentStatusText;
public StatusToolTip(@NotNull Project project) {
myProject = project;
}
@Nullable
public String getText() {
if (myCurrentRepository != null) {
return prepareToolTip();
} else {
return null;
}
}
private String prepareToolTip() {
StringBand infoPart = prepareInfoToolTipPart();
if (infoPart.length() > 0) {
infoPart.append(Html.br);
}
if (myCurrentStatusText == null) {
myCurrentStatusText = prepareStatusTooltip();
}
infoPart.append(myCurrentStatusText);
return infoPart.toString();
}
private String prepareStatusTooltip() {
StringBand infoPart = new StringBand();
Collection<GitRepository> repositories = GitUtil.getRepositories(myProject);
if (repositories.size() == 1) {
PerRepoInfoCache cache = GitToolBoxProject.getInstance(myProject).perRepoStatusCache();
RepoInfo info = cache.getInfo(myCurrentRepository);
if (info.count != null) {
infoPart.append(StatusText.formatToolTip(info.count));
}
} else if (repositories.size() > 2) {
prepareMultiRepoTooltip(infoPart, repositories);
}
return infoPart.toString();
}
private void prepareMultiRepoTooltip(StringBand infoPart, Collection<GitRepository> repositories) {
PerRepoInfoCache cache = GitToolBoxProject.getInstance(myProject).perRepoStatusCache();
Map<GitRepository, String> statuses = new LinkedHashMap<>();
final AtomicReference<GitRepository> currentRepo = new AtomicReference<>();
for (GitRepository repository : GtUtil.sort(repositories)) {
GitAheadBehindCount count = cache.getInfo(repository).count;
if (count != null) {
String statusText = StatusText.format(count);
if (repository.equals(myCurrentRepository)) {
currentRepo.set(repository);
}
statuses.put(repository, statusText);
}
}
if (!statuses.isEmpty()) {
if (infoPart.length() > 0) {
infoPart.append(Html.hr);
}
infoPart.append(
statuses.entrySet().stream().map(e -> {
String repoStatus = GitUIUtil.bold(GtUtil.name(e.getKey())) + ": " + e.getValue();
if (Objects.equals(e.getKey(), currentRepo.get())) {
repoStatus = Html.u(repoStatus);
}
return repoStatus;
}).collect(Collectors.joining(Html.br))
);
}
}
private StringBand prepareInfoToolTipPart() {
GitToolBoxConfigForProject config = GitToolBoxConfigForProject.getInstance(myProject);
StringBand result = new StringBand();
if (config.autoFetch) {
result.append(GitUIUtil.bold(ResBundle.getString("message.autoFetch"))).append(": ");
long lastAutoFetch = AutoFetch.getInstance(myProject).lastAutoFetch();
if (lastAutoFetch != 0) {
result.append(DateFormatUtil.formatBetweenDates(lastAutoFetch, System.currentTimeMillis()));
} else {
result.append(ResBundle.getString("common.on"));
}
}
return result;
}
public void update(@NotNull GitRepository repository, @Nullable GitAheadBehindCount aheadBehind) {
myCurrentRepository = repository;
myCurrentStatusText = null;
}
public void clear() {
myCurrentRepository = null;
myCurrentStatusText = null;
}
}