package com.atlassian.bitbucket.ssh.event;

import com.atlassian.bitbucket.audit.AuditEntry;
import com.atlassian.bitbucket.audit.AuditEntryBuilder;
import com.atlassian.bitbucket.audit.AuditEntryConverter;
import com.atlassian.bitbucket.ssh.SshKey;
import com.atlassian.bitbucket.user.ApplicationUser;
import com.atlassian.bitbucket.util.AuditUtils;
import com.google.common.collect.ImmutableMap;

import javax.annotation.Nonnull;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * {@link AuditEntryConverter} for {@link SshKeyEvent}s. This converter is used to integrate
 * {@link SshKeyEvent}s with the auditing system.
 */
public class SshKeyEventConverter implements AuditEntryConverter<SshKeyEvent> {

    @Nonnull
    @Override
    public AuditEntry convert(@Nonnull SshKeyEvent event, AuditEntryBuilder builder) {
        SshKey key = checkNotNull(checkNotNull(event, "event").getKey(), "event.key");
        Map<String, Object> details = new LinkedHashMap<>();
        details.put("id", key.getId());
        details.put("public-key", key.getText());
        if (key.getLabel() != null) {
                details.put("label", key.getLabel());
        }

        String target;
        ApplicationUser user = key.getUser();
        if (user != null) {
            details.put("user", createUserMap(user));
            target = user.getSlug();
        } else {
            target = "Global";
        }

        return builder
                .action(event.getClass())
                .timestamp(new Date())
                .details(AuditUtils.toJson(details))
                .user(event.getUser())
                .target(target)
                .build();
    }

    private static Map<String, Object> createUserMap(ApplicationUser user) {
        return ImmutableMap.<String, Object>builder()
                .put("id", user.getId())
                .put("name", user.getName())
                .put("slug", user.getSlug())
                .build();
    }
}
