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

package io.sentry;

import io.sentry.util.CollectionUtils;
import java.util.Iterator;
import java.util.Collections;
import java.util.ArrayList;
import io.sentry.protocol.SentryStackFrame;
import java.util.List;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.ApiStatus;

@ApiStatus.Internal
public final class SentryStackTraceFactory
{
    private static final int STACKTRACE_FRAME_LIMIT = 100;
    @NotNull
    private final SentryOptions options;
    
    public SentryStackTraceFactory(@NotNull final SentryOptions options) {
        this.options = options;
    }
    
    @Nullable
    public List<SentryStackFrame> getStackFrames(@Nullable final StackTraceElement[] elements, final boolean includeSentryFrames) {
        List<SentryStackFrame> sentryStackFrames = null;
        if (elements != null && elements.length > 0) {
            sentryStackFrames = new ArrayList<SentryStackFrame>();
            for (final StackTraceElement item : elements) {
                if (item != null) {
                    final String className = item.getClassName();
                    if (includeSentryFrames || !className.startsWith("io.sentry.") || className.startsWith("io.sentry.samples.") || className.startsWith("io.sentry.mobile.")) {
                        final SentryStackFrame sentryStackFrame = new SentryStackFrame();
                        sentryStackFrame.setInApp(this.isInApp(className));
                        sentryStackFrame.setModule(className);
                        sentryStackFrame.setFunction(item.getMethodName());
                        sentryStackFrame.setFilename(item.getFileName());
                        if (item.getLineNumber() >= 0) {
                            sentryStackFrame.setLineno(item.getLineNumber());
                        }
                        sentryStackFrame.setNative(item.isNativeMethod());
                        sentryStackFrames.add(sentryStackFrame);
                        if (sentryStackFrames.size() >= 100) {
                            break;
                        }
                    }
                }
            }
            Collections.reverse(sentryStackFrames);
        }
        return sentryStackFrames;
    }
    
    @Nullable
    public Boolean isInApp(@Nullable final String className) {
        if (className == null || className.isEmpty()) {
            return true;
        }
        final List<String> inAppIncludes = this.options.getInAppIncludes();
        for (final String include : inAppIncludes) {
            if (className.startsWith(include)) {
                return true;
            }
        }
        final List<String> inAppExcludes = this.options.getInAppExcludes();
        for (final String exclude : inAppExcludes) {
            if (className.startsWith(exclude)) {
                return false;
            }
        }
        return null;
    }
    
    @NotNull
    List<SentryStackFrame> getInAppCallStack(@NotNull final Throwable exception) {
        final StackTraceElement[] stacktrace = exception.getStackTrace();
        final List<SentryStackFrame> frames = this.getStackFrames(stacktrace, false);
        if (frames == null) {
            return Collections.emptyList();
        }
        final List<SentryStackFrame> inAppFrames = CollectionUtils.filterListEntries(frames, frame -> Boolean.TRUE.equals(frame.isInApp()));
        if (!inAppFrames.isEmpty()) {
            return inAppFrames;
        }
        return CollectionUtils.filterListEntries(frames, frame -> {
            final String module = frame.getModule();
            boolean isSystemFrame = false;
            if (module != null) {
                isSystemFrame = (module.startsWith("sun.") || module.startsWith("java.") || module.startsWith("android.") || module.startsWith("com.android."));
            }
            return !isSystemFrame;
        });
    }
    
    @ApiStatus.Internal
    @NotNull
    public List<SentryStackFrame> getInAppCallStack() {
        return this.getInAppCallStack(new Exception());
    }
}
