// 
// Decompiled by Procyon v0.6.0
// 

package io.sentry.protocol;

import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import io.sentry.vendor.gson.stream.JsonToken;
import io.sentry.ObjectReader;
import io.sentry.JsonDeserializer;
import java.io.IOException;
import io.sentry.ILogger;
import io.sentry.ObjectWriter;
import io.sentry.TracesSamplingDecision;
import io.sentry.SpanStatus;
import org.jetbrains.annotations.ApiStatus;
import java.util.Collection;
import io.sentry.featureflags.IFeatureFlagBuffer;
import java.util.Iterator;
import io.sentry.SpanContext;
import io.sentry.Span;
import io.sentry.DateUtils;
import io.sentry.util.Objects;
import java.util.HashMap;
import java.util.ArrayList;
import io.sentry.SentryTracer;
import java.util.Map;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import io.sentry.JsonSerializable;
import io.sentry.JsonUnknown;
import io.sentry.SentryBaseEvent;

public final class SentryTransaction extends SentryBaseEvent implements JsonUnknown, JsonSerializable
{
    @Nullable
    private String transaction;
    @NotNull
    private Double startTimestamp;
    @Nullable
    private Double timestamp;
    @NotNull
    private final List<SentrySpan> spans;
    @NotNull
    private final String type = "transaction";
    @NotNull
    private final Map<String, MeasurementValue> measurements;
    @NotNull
    private TransactionInfo transactionInfo;
    @Nullable
    private Map<String, Object> unknown;
    
    public SentryTransaction(@NotNull final SentryTracer sentryTracer) {
        super(sentryTracer.getEventId());
        this.spans = new ArrayList<SentrySpan>();
        this.measurements = new HashMap<String, MeasurementValue>();
        Objects.requireNonNull(sentryTracer, "sentryTracer is required");
        this.startTimestamp = DateUtils.nanosToSeconds(sentryTracer.getStartDate().nanoTimestamp());
        this.timestamp = DateUtils.nanosToSeconds(sentryTracer.getStartDate().laterDateNanosTimestampByDiff(sentryTracer.getFinishDate()));
        this.transaction = sentryTracer.getName();
        for (final Span span : sentryTracer.getChildren()) {
            if (Boolean.TRUE.equals(span.isSampled())) {
                this.spans.add(new SentrySpan(span));
            }
        }
        final Contexts contexts = this.getContexts();
        contexts.putAll(sentryTracer.getContexts());
        final SpanContext tracerContext = sentryTracer.getSpanContext();
        final Map<String, Object> data = sentryTracer.getData();
        final SpanContext tracerContextToSend = new SpanContext(tracerContext.getTraceId(), tracerContext.getSpanId(), tracerContext.getParentSpanId(), tracerContext.getOperation(), tracerContext.getDescription(), tracerContext.getSamplingDecision(), tracerContext.getStatus(), tracerContext.getOrigin());
        for (final Map.Entry<String, String> tag : tracerContext.getTags().entrySet()) {
            this.setTag(tag.getKey(), tag.getValue());
        }
        if (data != null) {
            for (final Map.Entry<String, Object> tag2 : data.entrySet()) {
                tracerContextToSend.setData(tag2.getKey(), tag2.getValue());
            }
        }
        final IFeatureFlagBuffer featureFlagBuffer = tracerContext.getFeatureFlagBuffer();
        final FeatureFlags featureFlags = featureFlagBuffer.getFeatureFlags();
        if (featureFlags != null) {
            for (final FeatureFlag featureFlag : featureFlags.getValues()) {
                tracerContextToSend.setData("flag.evaluation." + featureFlag.getFlag(), featureFlag.getResult());
            }
        }
        contexts.setTrace(tracerContextToSend);
        this.transactionInfo = new TransactionInfo(sentryTracer.getTransactionNameSource().apiName());
    }
    
    @ApiStatus.Internal
    public SentryTransaction(@Nullable final String transaction, @NotNull final Double startTimestamp, @Nullable final Double timestamp, @NotNull final List<SentrySpan> spans, @NotNull final Map<String, MeasurementValue> measurements, @NotNull final TransactionInfo transactionInfo) {
        this.spans = new ArrayList<SentrySpan>();
        this.measurements = new HashMap<String, MeasurementValue>();
        this.transaction = transaction;
        this.startTimestamp = startTimestamp;
        this.timestamp = timestamp;
        this.spans.addAll(spans);
        this.measurements.putAll(measurements);
        for (final SentrySpan span : spans) {
            this.measurements.putAll(span.getMeasurements());
        }
        this.transactionInfo = transactionInfo;
    }
    
    @NotNull
    public List<SentrySpan> getSpans() {
        return this.spans;
    }
    
    public boolean isFinished() {
        return this.timestamp != null;
    }
    
    @Nullable
    public String getTransaction() {
        return this.transaction;
    }
    
    @NotNull
    public Double getStartTimestamp() {
        return this.startTimestamp;
    }
    
    @Nullable
    public Double getTimestamp() {
        return this.timestamp;
    }
    
    @NotNull
    public String getType() {
        return "transaction";
    }
    
    @Nullable
    public SpanStatus getStatus() {
        final SpanContext trace = this.getContexts().getTrace();
        return (trace != null) ? trace.getStatus() : null;
    }
    
    public boolean isSampled() {
        final TracesSamplingDecision samplingDecsion = this.getSamplingDecision();
        return samplingDecsion != null && samplingDecsion.getSampled();
    }
    
    @Nullable
    public TracesSamplingDecision getSamplingDecision() {
        final SpanContext trace = this.getContexts().getTrace();
        if (trace == null) {
            return null;
        }
        return trace.getSamplingDecision();
    }
    
    @NotNull
    public Map<String, MeasurementValue> getMeasurements() {
        return this.measurements;
    }
    
    @Override
    public void serialize(@NotNull final ObjectWriter writer, @NotNull final ILogger logger) throws IOException {
        writer.beginObject();
        if (this.transaction != null) {
            writer.name("transaction").value(this.transaction);
        }
        writer.name("start_timestamp").value(logger, DateUtils.doubleToBigDecimal(this.startTimestamp));
        if (this.timestamp != null) {
            writer.name("timestamp").value(logger, DateUtils.doubleToBigDecimal(this.timestamp));
        }
        if (!this.spans.isEmpty()) {
            writer.name("spans").value(logger, this.spans);
        }
        writer.name("type").value("transaction");
        if (!this.measurements.isEmpty()) {
            writer.name("measurements").value(logger, this.measurements);
        }
        writer.name("transaction_info").value(logger, this.transactionInfo);
        new Serializer().serialize(this, writer, logger);
        if (this.unknown != null) {
            for (final String key : this.unknown.keySet()) {
                final Object value = this.unknown.get(key);
                writer.name(key);
                writer.value(logger, value);
            }
        }
        writer.endObject();
    }
    
    @Nullable
    @Override
    public Map<String, Object> getUnknown() {
        return this.unknown;
    }
    
    @Override
    public void setUnknown(@Nullable final Map<String, Object> unknown) {
        this.unknown = unknown;
    }
    
    public static final class JsonKeys
    {
        public static final String TRANSACTION = "transaction";
        public static final String START_TIMESTAMP = "start_timestamp";
        public static final String TIMESTAMP = "timestamp";
        public static final String SPANS = "spans";
        public static final String TYPE = "type";
        public static final String MEASUREMENTS = "measurements";
        public static final String TRANSACTION_INFO = "transaction_info";
    }
    
    public static final class Deserializer implements JsonDeserializer<SentryTransaction>
    {
        @NotNull
        @Override
        public SentryTransaction deserialize(@NotNull final ObjectReader reader, @NotNull final ILogger logger) throws Exception {
            reader.beginObject();
            final SentryTransaction transaction = new SentryTransaction("", 0.0, null, new ArrayList<SentrySpan>(), new HashMap<String, MeasurementValue>(), new TransactionInfo(TransactionNameSource.CUSTOM.apiName()));
            Map<String, Object> unknown = null;
            final SentryBaseEvent.Deserializer baseEventDeserializer = new SentryBaseEvent.Deserializer();
            while (reader.peek() == JsonToken.NAME) {
                final String nextName2;
                final String nextName = nextName2 = reader.nextName();
                switch (nextName2) {
                    case "transaction": {
                        transaction.transaction = reader.nextStringOrNull();
                        continue;
                    }
                    case "start_timestamp": {
                        try {
                            final Double deserializedStartTimestamp = reader.nextDoubleOrNull();
                            if (deserializedStartTimestamp == null) {
                                continue;
                            }
                            transaction.startTimestamp = deserializedStartTimestamp;
                        }
                        catch (final NumberFormatException e) {
                            final Date date = reader.nextDateOrNull(logger);
                            if (date == null) {
                                continue;
                            }
                            transaction.startTimestamp = DateUtils.dateToSeconds(date);
                        }
                        continue;
                    }
                    case "timestamp": {
                        try {
                            final Double deserializedTimestamp = reader.nextDoubleOrNull();
                            if (deserializedTimestamp == null) {
                                continue;
                            }
                            transaction.timestamp = deserializedTimestamp;
                        }
                        catch (final NumberFormatException e) {
                            final Date date = reader.nextDateOrNull(logger);
                            if (date == null) {
                                continue;
                            }
                            transaction.timestamp = DateUtils.dateToSeconds(date);
                        }
                        continue;
                    }
                    case "spans": {
                        final List<SentrySpan> deserializedSpans = reader.nextListOrNull(logger, (JsonDeserializer<SentrySpan>)new SentrySpan.Deserializer());
                        if (deserializedSpans != null) {
                            transaction.spans.addAll(deserializedSpans);
                            continue;
                        }
                        continue;
                    }
                    case "type": {
                        reader.nextString();
                        continue;
                    }
                    case "measurements": {
                        final Map<String, MeasurementValue> deserializedMeasurements = reader.nextMapOrNull(logger, (JsonDeserializer<MeasurementValue>)new MeasurementValue.Deserializer());
                        if (deserializedMeasurements != null) {
                            transaction.measurements.putAll(deserializedMeasurements);
                            continue;
                        }
                        continue;
                    }
                    case "transaction_info": {
                        transaction.transactionInfo = new TransactionInfo.Deserializer().deserialize(reader, logger);
                        continue;
                    }
                    default: {
                        if (!baseEventDeserializer.deserializeValue(transaction, nextName, reader, logger)) {
                            if (unknown == null) {
                                unknown = new ConcurrentHashMap<String, Object>();
                            }
                            reader.nextUnknown(logger, unknown, nextName);
                            continue;
                        }
                        continue;
                    }
                }
            }
            transaction.setUnknown(unknown);
            reader.endObject();
            return transaction;
        }
    }
}
