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

package io.sentry.cache;

import io.sentry.JsonDeserializer;
import io.sentry.protocol.SentryId;
import io.sentry.protocol.Contexts;
import io.sentry.IScope;
import io.sentry.SpanContext;
import io.sentry.protocol.Request;
import java.util.Map;
import java.util.Collection;
import io.sentry.protocol.User;
import java.io.Writer;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.OutputStream;
import org.jetbrains.annotations.Nullable;
import java.io.Reader;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import io.sentry.cache.tape.QueueFile;
import java.io.File;
import io.sentry.SentryLevel;
import io.sentry.Breadcrumb;
import io.sentry.cache.tape.ObjectQueue;
import io.sentry.util.LazyEvaluator;
import org.jetbrains.annotations.NotNull;
import io.sentry.SentryOptions;
import java.nio.charset.Charset;
import io.sentry.ScopeObserverAdapter;

public final class PersistingScopeObserver extends ScopeObserverAdapter
{
    private static final Charset UTF_8;
    public static final String SCOPE_CACHE = ".scope-cache";
    public static final String USER_FILENAME = "user.json";
    public static final String BREADCRUMBS_FILENAME = "breadcrumbs.json";
    public static final String TAGS_FILENAME = "tags.json";
    public static final String EXTRAS_FILENAME = "extras.json";
    public static final String CONTEXTS_FILENAME = "contexts.json";
    public static final String REQUEST_FILENAME = "request.json";
    public static final String LEVEL_FILENAME = "level.json";
    public static final String FINGERPRINT_FILENAME = "fingerprint.json";
    public static final String TRANSACTION_FILENAME = "transaction.json";
    public static final String TRACE_FILENAME = "trace.json";
    public static final String REPLAY_FILENAME = "replay.json";
    @NotNull
    private SentryOptions options;
    @NotNull
    private final LazyEvaluator<ObjectQueue<Breadcrumb>> breadcrumbsQueue;
    
    public PersistingScopeObserver(@NotNull final SentryOptions options) {
        this.breadcrumbsQueue = new LazyEvaluator<ObjectQueue<Breadcrumb>>(() -> {
            final File cacheDir = CacheUtils.ensureCacheDir(this.options, ".scope-cache");
            if (cacheDir == null) {
                this.options.getLogger().log(SentryLevel.INFO, "Cache dir is not set, cannot store in scope cache", new Object[0]);
                return ObjectQueue.createEmpty();
            }
            else {
                final QueueFile queueFile = null;
                final File file = new File(cacheDir, "breadcrumbs.json");
                QueueFile queueFile2;
                try {
                    try {
                        queueFile2 = new QueueFile.Builder(file).size(this.options.getMaxBreadcrumbs()).build();
                    }
                    catch (final IOException e) {
                        file.delete();
                        queueFile2 = new QueueFile.Builder(file).size(this.options.getMaxBreadcrumbs()).build();
                    }
                }
                catch (final IOException e2) {
                    this.options.getLogger().log(SentryLevel.ERROR, "Failed to create breadcrumbs queue", e2);
                    return ObjectQueue.createEmpty();
                }
                return ObjectQueue.create(queueFile2, (ObjectQueue.Converter<Object>)new ObjectQueue.Converter<Breadcrumb>() {
                    @Nullable
                    @Override
                    public Breadcrumb from(final byte[] source) {
                        try (final Reader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(source), PersistingScopeObserver.UTF_8))) {
                            return PersistingScopeObserver.this.options.getSerializer().deserialize(reader, Breadcrumb.class);
                        }
                        catch (final Throwable e) {
                            PersistingScopeObserver.this.options.getLogger().log(SentryLevel.ERROR, e, "Error reading entity from scope cache", new Object[0]);
                            return null;
                        }
                    }
                    
                    @Override
                    public void toStream(final Breadcrumb value, final OutputStream sink) throws IOException {
                        try (final Writer writer = new BufferedWriter(new OutputStreamWriter(sink, PersistingScopeObserver.UTF_8))) {
                            PersistingScopeObserver.this.options.getSerializer().serialize(value, writer);
                        }
                    }
                });
            }
        });
        this.options = options;
    }
    
    @Override
    public void setUser(@Nullable final User user) {
        this.serializeToDisk(() -> {
            if (user == null) {
                this.delete("user.json");
            }
            else {
                this.store(user, "user.json");
            }
        });
    }
    
    @Override
    public void addBreadcrumb(@NotNull final Breadcrumb crumb) {
        this.serializeToDisk(() -> {
            try {
                this.breadcrumbsQueue.getValue().add(crumb);
            }
            catch (final IOException e) {
                this.options.getLogger().log(SentryLevel.ERROR, "Failed to add breadcrumb to file queue", e);
            }
        });
    }
    
    @Override
    public void setBreadcrumbs(@NotNull final Collection<Breadcrumb> breadcrumbs) {
        if (breadcrumbs.isEmpty()) {
            this.serializeToDisk(() -> {
                try {
                    this.breadcrumbsQueue.getValue().clear();
                }
                catch (final IOException e) {
                    this.options.getLogger().log(SentryLevel.ERROR, "Failed to clear breadcrumbs from file queue", e);
                }
            });
        }
    }
    
    @Override
    public void setTags(@NotNull final Map<String, String> tags) {
        this.serializeToDisk(() -> this.store(tags, "tags.json"));
    }
    
    @Override
    public void setExtras(@NotNull final Map<String, Object> extras) {
        this.serializeToDisk(() -> this.store(extras, "extras.json"));
    }
    
    @Override
    public void setRequest(@Nullable final Request request) {
        this.serializeToDisk(() -> {
            if (request == null) {
                this.delete("request.json");
            }
            else {
                this.store(request, "request.json");
            }
        });
    }
    
    @Override
    public void setFingerprint(@NotNull final Collection<String> fingerprint) {
        this.serializeToDisk(() -> this.store(fingerprint, "fingerprint.json"));
    }
    
    @Override
    public void setLevel(@Nullable final SentryLevel level) {
        this.serializeToDisk(() -> {
            if (level == null) {
                this.delete("level.json");
            }
            else {
                this.store(level, "level.json");
            }
        });
    }
    
    @Override
    public void setTransaction(@Nullable final String transaction) {
        this.serializeToDisk(() -> {
            if (transaction == null) {
                this.delete("transaction.json");
            }
            else {
                this.store(transaction, "transaction.json");
            }
        });
    }
    
    @Override
    public void setTrace(@Nullable final SpanContext spanContext, @NotNull final IScope scope) {
        this.serializeToDisk(() -> {
            if (spanContext == null) {
                this.store(scope.getPropagationContext().toSpanContext(), "trace.json");
            }
            else {
                this.store(spanContext, "trace.json");
            }
        });
    }
    
    @Override
    public void setContexts(@NotNull final Contexts contexts) {
        this.serializeToDisk(() -> this.store(contexts, "contexts.json"));
    }
    
    @Override
    public void setReplayId(@NotNull final SentryId replayId) {
        this.serializeToDisk(() -> this.store(replayId, "replay.json"));
    }
    
    private void serializeToDisk(@NotNull final Runnable task) {
        if (!this.options.isEnableScopePersistence()) {
            return;
        }
        if (Thread.currentThread().getName().contains("SentryExecutor")) {
            try {
                task.run();
            }
            catch (final Throwable e) {
                this.options.getLogger().log(SentryLevel.ERROR, "Serialization task failed", e);
            }
            return;
        }
        try {
            this.options.getExecutorService().submit(() -> {
                try {
                    task.run();
                }
                catch (final Throwable e2) {
                    this.options.getLogger().log(SentryLevel.ERROR, "Serialization task failed", e2);
                }
            });
        }
        catch (final Throwable e) {
            this.options.getLogger().log(SentryLevel.ERROR, "Serialization task could not be scheduled", e);
        }
    }
    
    private <T> void store(@NotNull final T entity, @NotNull final String fileName) {
        store(this.options, entity, fileName);
    }
    
    private void delete(@NotNull final String fileName) {
        CacheUtils.delete(this.options, ".scope-cache", fileName);
    }
    
    public static <T> void store(@NotNull final SentryOptions options, @NotNull final T entity, @NotNull final String fileName) {
        CacheUtils.store(options, entity, ".scope-cache", fileName);
    }
    
    @Nullable
    public <T> T read(@NotNull final SentryOptions options, @NotNull final String fileName, @NotNull final Class<T> clazz) {
        if (fileName.equals("breadcrumbs.json")) {
            try {
                return clazz.cast(this.breadcrumbsQueue.getValue().asList());
            }
            catch (final IOException e) {
                options.getLogger().log(SentryLevel.ERROR, "Unable to read serialized breadcrumbs from QueueFile", new Object[0]);
                return null;
            }
        }
        return CacheUtils.read(options, ".scope-cache", fileName, clazz, (JsonDeserializer<Object>)null);
    }
    
    public void resetCache() {
        try {
            this.breadcrumbsQueue.getValue().clear();
        }
        catch (final IOException e) {
            this.options.getLogger().log(SentryLevel.ERROR, "Failed to clear breadcrumbs from file queue", e);
        }
        this.delete("user.json");
        this.delete("level.json");
        this.delete("request.json");
        this.delete("fingerprint.json");
        this.delete("contexts.json");
        this.delete("extras.json");
        this.delete("tags.json");
        this.delete("trace.json");
        this.delete("transaction.json");
    }
    
    static {
        UTF_8 = Charset.forName("UTF-8");
    }
}
