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

package io.sentry;

import io.sentry.protocol.SentryStackFrame;
import io.sentry.protocol.SentryStackTrace;
import org.jetbrains.annotations.TestOnly;
import java.util.Iterator;
import java.util.ArrayList;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.HashMap;
import io.sentry.protocol.SentryThread;
import java.util.List;
import io.sentry.util.Objects;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.ApiStatus;

@ApiStatus.Internal
public final class SentryThreadFactory
{
    @NotNull
    private final SentryStackTraceFactory sentryStackTraceFactory;
    
    public SentryThreadFactory(@NotNull final SentryStackTraceFactory sentryStackTraceFactory) {
        this.sentryStackTraceFactory = Objects.requireNonNull(sentryStackTraceFactory, "The SentryStackTraceFactory is required.");
    }
    
    @Nullable
    List<SentryThread> getCurrentThread(final boolean attachStackTrace) {
        final Map<Thread, StackTraceElement[]> threads = new HashMap<Thread, StackTraceElement[]>();
        final Thread currentThread = Thread.currentThread();
        threads.put(currentThread, currentThread.getStackTrace());
        return this.getCurrentThreads(threads, null, false, attachStackTrace);
    }
    
    @Nullable
    List<SentryThread> getCurrentThreads(@Nullable final List<Long> mechanismThreadIds, final boolean ignoreCurrentThread, final boolean attachStackTrace) {
        return this.getCurrentThreads(Thread.getAllStackTraces(), mechanismThreadIds, ignoreCurrentThread, attachStackTrace);
    }
    
    @Nullable
    List<SentryThread> getCurrentThreads(@Nullable final List<Long> mechanismThreadIds, final boolean attachStackTrace) {
        return this.getCurrentThreads(Thread.getAllStackTraces(), mechanismThreadIds, false, attachStackTrace);
    }
    
    @TestOnly
    @Nullable
    List<SentryThread> getCurrentThreads(@NotNull final Map<Thread, StackTraceElement[]> threads, @Nullable final List<Long> mechanismThreadIds, final boolean ignoreCurrentThread, final boolean attachStackTrace) {
        List<SentryThread> result = null;
        final Thread currentThread = Thread.currentThread();
        if (!threads.isEmpty()) {
            result = new ArrayList<SentryThread>();
            if (!threads.containsKey(currentThread)) {
                threads.put(currentThread, currentThread.getStackTrace());
            }
            for (final Map.Entry<Thread, StackTraceElement[]> item : threads.entrySet()) {
                final Thread thread = item.getKey();
                final boolean crashed = (thread == currentThread && !ignoreCurrentThread) || (mechanismThreadIds != null && mechanismThreadIds.contains(thread.getId()) && !ignoreCurrentThread);
                result.add(this.getSentryThread(crashed, item.getValue(), item.getKey(), attachStackTrace));
            }
        }
        return result;
    }
    
    @NotNull
    private SentryThread getSentryThread(final boolean crashed, @NotNull final StackTraceElement[] stackFramesElements, @NotNull final Thread thread, final boolean attachStacktrace) {
        final SentryThread sentryThread = new SentryThread();
        sentryThread.setName(thread.getName());
        sentryThread.setPriority(thread.getPriority());
        sentryThread.setId(thread.getId());
        sentryThread.setDaemon(thread.isDaemon());
        sentryThread.setState(thread.getState().name());
        sentryThread.setCrashed(crashed);
        if (attachStacktrace) {
            final List<SentryStackFrame> frames = this.sentryStackTraceFactory.getStackFrames(stackFramesElements, false);
            if (frames != null && !frames.isEmpty()) {
                final SentryStackTrace sentryStackTrace = new SentryStackTrace(frames);
                sentryStackTrace.setSnapshot(true);
                sentryThread.setStacktrace(sentryStackTrace);
            }
        }
        return sentryThread;
    }
}
