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

import com.atlassian.bitbucket.repository.sync.RefSyncStatus;
import com.atlassian.bitbucket.repository.sync.RejectedRef;
import com.atlassian.bitbucket.rest.annotation.JsonSurrogate;
import com.atlassian.bitbucket.rest.RestMapEntity;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import org.codehaus.jackson.map.annotate.JsonSerialize;

import java.util.Collections;
import java.util.Set;

/**
 * @since 2.6
 */
@JsonSerialize
@JsonSurrogate(RefSyncStatus.class)
public class RestRefSyncStatus extends RestMapEntity {

    public static final String ENABLED = "enabled";

    private static final String AHEAD_REFS = "aheadRefs";
    private static final String AVAILABLE = "available";
    private static final String DIVERGED_REFS = "divergedRefs";
    private static final String LAST_SYNC = "lastSync";
    private static final String ORPHANED_REFS = "orphanedRefs";

    @SuppressWarnings("unused") //For Jersey
    public RestRefSyncStatus() {
    }

    public RestRefSyncStatus(boolean available) {
        put(AVAILABLE, available);
        put(ENABLED, false);
    }

    public RestRefSyncStatus(RefSyncStatus status) {
        put(AVAILABLE, status.isAvailable());
        put(ENABLED, status.isEnabled());
        put(LAST_SYNC, status.getLastSync());
        if (status.isEnabled()) {
            putRefs(AHEAD_REFS, status.getAheadRefs());
            putRefs(DIVERGED_REFS, status.getDivergedRefs());
            putRefs(ORPHANED_REFS, status.getOrphanedRefs());
        }
    }

    public boolean isEnabled() {
        return getBoolProperty(ENABLED, true);
    }

    private void putRefs(String key, Set<RejectedRef> refs) {
        put(key, ImmutableList.copyOf(Collections2.transform(refs, RestRejectedRef.REST_TRANSFORM)));
    }

    // REST Documentation Examples
    public static final RestRefSyncStatus REQUEST_EXAMPLE = new RestRefSyncStatus() { {
        put(ENABLED, true);
    } };
    public static final RestRefSyncStatus RESPONSE_EXAMPLE = new RestRefSyncStatus() { {
        put(AVAILABLE, true);
        put(ENABLED, true);
        put(LAST_SYNC, 1331038800000L);
        put(AHEAD_REFS, Collections.emptySet());
        put(DIVERGED_REFS, Collections.singleton(RestRejectedRef.DIVERGED_EXAMPLE));
        put(ORPHANED_REFS, Collections.emptySet());
    } };
}
