package at.procon.eventhub.service;

import at.procon.eventhub.dto.EventHubEventDto;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.springframework.stereotype.Component;

@Component
public class EventNaturalKeyService {

    /**
     * Canonical event key intentionally excludes EventSource. VU and driver-card
     * acquisitions of the same real-world event can therefore converge later when
     * storage/deduplication is implemented.
     *
     * Because incoming acquisition requests usually do not know internal master
     * ids, this acquisition-stage key uses tenant + source-side master references.
     * Late master-data resolution can later rebuild a stronger canonical key.
     */
    public String buildCanonicalKeyHash(EventHubEventDto event) {
        String naturalKey = String.join("|",
                nullToEmpty(event.packageInfo() == null ? null : event.packageInfo().tenantKey()),
                nullToEmpty(event.driverRef() == null ? null : event.driverRef().stableKey()),
                nullToEmpty(event.vehicleRef() == null ? null : event.vehicleRef().stableKey()),
                nullToEmpty(event.occurredAt()),
                nullToEmpty(event.eventDomain()),
                nullToEmpty(event.eventType()),
                nullToEmpty(event.lifecycle())
        );
        return sha256Hex(naturalKey);
    }

    /** Source-record key includes the source id and external source event id. */
    public String buildSourceRecordKeyHash(EventHubEventDto event, int eventSourceId) {
        String sourceRecordKey = String.join("|",
                nullToEmpty(event.packageInfo() == null ? null : event.packageInfo().tenantKey()),
                String.valueOf(eventSourceId),
                nullToEmpty(event.externalSourceEventId())
        );
        return sha256Hex(sourceRecordKey);
    }

    private String nullToEmpty(Object value) {
        return value == null ? "" : String.valueOf(value);
    }

    private String sha256Hex(String value) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(value.getBytes(StandardCharsets.UTF_8));
            StringBuilder result = new StringBuilder(hash.length * 2);
            for (byte b : hash) {
                result.append(String.format("%02x", b));
            }
            return result.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException("SHA-256 is not available", e);
        }
    }
}
