package com.atlassian.bitbucket.internal.mirroring.mirror.rest.webhook.cloud;

import com.atlassian.bitbucket.internal.mirroring.mirror.rest.RestUnknownEntity;
import com.atlassian.bitbucket.internal.mirroring.mirror.rest.webhook.UpstreamWebHookEventId;
import org.slf4j.Logger;

import javax.annotation.Nonnull;
import java.util.Arrays;
import java.util.Optional;

import static com.atlassian.bitbucket.internal.mirroring.mirror.rest.webhook.cloud.RestCloudWebHookPropertyNames.EVENT;
import static java.util.Optional.empty;
import static java.util.Optional.of;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Web hook event ids from a cloud upstream that the mirror is interested in
 */
public enum CloudWebHookEventId implements UpstreamWebHookEventId {

    PROJECT_UPDATED("project:updated"),
    REPOSITORY_CREATED("repo:created"),
    REPOSITORY_DELETED("repo:deleted"),
    REPOSITORY_IMPORTED("repo:imported"),
    REPOSITORY_PUSH("repo:push"),
    REPOSITORY_UPDATED("repo:updated");

    private static final Logger log = getLogger(CloudWebHookEventId.class);

    private final String value;

    CloudWebHookEventId(@Nonnull String value) {
        this.value = value;
    }

    @Nonnull
    @Override
    public String getValue() {
        return value;
    }

    @Override
    public String toString() {
        return value;
    }

    @Nonnull
    public static Optional<CloudWebHookEventId> fromEntity(@Nonnull RestUnknownEntity unknownEntity) {
        String eventKey = (String) unknownEntity.get(EVENT);
        if (eventKey == null) {
            log.warn("Web hook event id not present for cloud web hook - unable to determine web hook type");
            return empty();
        }

        for (CloudWebHookEventId webHookEventId : values()) {
            if (webHookEventId.getValue().equals(eventKey)) {
                return of(webHookEventId);
            }
        }

        log.warn("Web hook event key {} does not match cloud web hooks of interest: {}",
                eventKey, Arrays.toString(CloudWebHookEventId.values()));

        return empty();
    }

}
