package com.atlassian.stash.internal.repository.sync.stp;

import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.repository.sync.RefSyncService;
import com.atlassian.bitbucket.repository.sync.RefSyncStatus;
import com.atlassian.support.tools.spi.SupportInfoAppender;
import com.atlassian.support.tools.spi.SupportInfoBuilder;

import java.text.DateFormat;
import java.util.Locale;

/**
 * Adds synchronization {@link RefSyncStatus status} information for each {@link Repository}.
 *
 * @since 2.6
 */
public class RefSyncSupportInfoAppender implements SupportInfoAppender<Repository> {

    //Note: While these are not synchronized internally, they are safe to use concurrently so long as their
    //      state is not modified. In other words, if no setters are called, format(Date) is thread-safe
    private static final DateFormat FORMAT = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.US);
    private static final String REF_SYNC = "stp.properties.stash.refsync";
    private static final String REF_SYNC_AHEAD = REF_SYNC + ".ahead";
    private static final String REF_SYNC_DIVERGED = REF_SYNC + ".diverged";
    private static final String REF_SYNC_ENABLED = REF_SYNC + ".enabled";
    private static final String REF_SYNC_LAST_SYNC = REF_SYNC + ".lastsync";
    private static final String REF_SYNC_ORPHANED = REF_SYNC + ".orphaned";

    private final RefSyncService refSyncService;

    public RefSyncSupportInfoAppender(RefSyncService refSyncService) {
        this.refSyncService = refSyncService;
    }

    @Override
    public void addSupportInfo(SupportInfoBuilder builder, Repository repository) {
        RefSyncStatus status = refSyncService.getStatus(repository);
        if (status == null) {
            return;
        }

        SupportInfoBuilder refSync = builder.addCategory(REF_SYNC);
        refSync.addValue(REF_SYNC_ENABLED, Boolean.toString(status.isEnabled()));
        refSync.addValue(REF_SYNC_LAST_SYNC, FORMAT.format(status.getLastSync()));
        if (status.isEnabled()) {
            //Outputting the specific values is unnecessary (and may have disclosure concerns). Just
            //including the counts is most likely equally useful
            refSync.addValue(REF_SYNC_AHEAD, Integer.toString(status.getAheadRefs().size()));
            refSync.addValue(REF_SYNC_DIVERGED, Integer.toString(status.getDivergedRefs().size()));
            refSync.addValue(REF_SYNC_ORPHANED, Integer.toString(status.getOrphanedRefs().size()));
        }
    }
}
