package com.atlassian.stash.internal.audit.external;

import com.atlassian.bitbucket.audit.AuditEntryBuilder;
import com.atlassian.event.api.EventListener;
import com.atlassian.event.api.EventPublisher;
import com.atlassian.plugin.event.events.*;
import com.atlassian.bitbucket.audit.AuditEntry;
import com.atlassian.bitbucket.audit.Priority;
import com.atlassian.bitbucket.event.audit.AuditEvent;
import com.atlassian.stash.internal.audit.AbstractAuditEventPublisher;
import com.atlassian.stash.internal.audit.AuditEntryLoggingService;
import com.atlassian.bitbucket.request.RequestManager;
import com.atlassian.bitbucket.auth.AuthenticationContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * Listens to events fired by the plugin framework and translates them to {@link AuditEvent audit events}
 *
 * @since 2.6
 */
@Component
public class PluginEventListener extends AbstractAuditEventPublisher {

    @Autowired
    public PluginEventListener(AuditEntryLoggingService auditLoggingService, RequestManager requestManager,
                               AuthenticationContext authContext, EventPublisher eventPublisher) {
        super(auditLoggingService, requestManager, authContext, eventPublisher);
    }

    @EventListener
    public void onPluginContainerUnavailable(PluginContainerUnavailableEvent event) throws Exception {
        AuditEntry auditEntry = createAuditEntryBuilder(event)
                .target(event.getPluginKey())
                .build();
        publish(event, auditEntry, Priority.LOW);
    }

    @EventListener
    public void onPluginDisabled(PluginDisabledEvent event) throws Exception {
        AuditEntry auditEntry = createAuditEntryBuilder(event)
                .target(event.getPlugin().getKey())
                .build();
        publish(event, auditEntry, Priority.MEDIUM);
    }

    @EventListener
    public void onPluginEnabled(PluginEnabledEvent event) throws Exception {
        AuditEntry auditEntry = createAuditEntryBuilder(event)
                .target(event.getPlugin().getKey())
                .build();
        publish(event, auditEntry, Priority.MEDIUM);
    }

    @EventListener
    public void onPluginFrameworkStarted(PluginFrameworkStartedEvent event) throws Exception {
        AuditEntry auditEntry = createAuditEntryBuilder(event)
                .target("Plugin Framework")
                .build();
        publish(event, auditEntry, Priority.LOW);
    }

    @EventListener
    public void onPluginModuleAvailable(PluginModuleAvailableEvent event) throws Exception {
        AuditEntry auditEntry = createAuditEntryBuilder(event)
                .target(event.getModule().getCompleteKey())
                .build();
        publish(event, auditEntry, Priority.LOW);
    }

    @EventListener
    public void onPluginModuleDisabled(PluginModuleDisabledEvent event) throws Exception {
        AuditEntry auditEntry = createAuditEntryBuilder(event)
                .target(event.getModule().getCompleteKey())
                .build();
        publish(event, auditEntry, Priority.MEDIUM);
    }

    @EventListener
    public void onPluginModuleEnabled(PluginModuleEnabledEvent event) throws Exception {
        AuditEntry auditEntry = createAuditEntryBuilder(event)
                .target(event.getModule().getCompleteKey())
                .build();
        publish(event, auditEntry, Priority.MEDIUM);
    }

    @EventListener
    public void onPluginModuleUnavailable(PluginModuleUnavailableEvent event) throws Exception {
        AuditEntry auditEntry = createAuditEntryBuilder(event)
                .target(event.getModule().getCompleteKey())
                .build();
        publish(event, auditEntry, Priority.MEDIUM);
    }

    @EventListener
    public void onPluginUninstalled(PluginUninstalledEvent event) throws Exception {
        AuditEntry auditEntry = createAuditEntryBuilder(event)
                .target(event.getPlugin().getKey())
                .build();
        publish(event, auditEntry, Priority.MEDIUM);
    }

    @EventListener
    public void onPluginUpgraded(PluginUpgradedEvent event) throws Exception {
        AuditEntry auditEntry = createAuditEntryBuilder(event)
                .target(event.getPlugin().getKey())
                .build();
        publish(event, auditEntry, Priority.MEDIUM);
    }

    private AuditEntryBuilder createAuditEntryBuilder(Object event) {
        return setCommonFields(event, new AuditEntryBuilder());
    }
}
