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

package io.sentry;

import java.util.Iterator;
import io.sentry.util.Objects;
import java.util.concurrent.LinkedBlockingDeque;
import io.sentry.util.AutoClosableReentrantLock;
import org.jetbrains.annotations.NotNull;
import java.util.Deque;

final class Stack
{
    @NotNull
    private final Deque<StackItem> items;
    @NotNull
    private final ILogger logger;
    @NotNull
    private final AutoClosableReentrantLock itemsLock;
    
    public Stack(@NotNull final ILogger logger, @NotNull final StackItem rootStackItem) {
        this.items = new LinkedBlockingDeque<StackItem>();
        this.itemsLock = new AutoClosableReentrantLock();
        this.logger = Objects.requireNonNull(logger, "logger is required");
        this.items.push(Objects.requireNonNull(rootStackItem, "rootStackItem is required"));
    }
    
    public Stack(@NotNull final Stack stack) {
        this(stack.logger, new StackItem(stack.items.getLast()));
        final Iterator<StackItem> iterator = stack.items.descendingIterator();
        if (iterator.hasNext()) {
            iterator.next();
        }
        while (iterator.hasNext()) {
            this.push(new StackItem(iterator.next()));
        }
    }
    
    @NotNull
    StackItem peek() {
        return this.items.peek();
    }
    
    void pop() {
        try (final ISentryLifecycleToken ignored = this.itemsLock.acquire()) {
            if (this.items.size() != 1) {
                this.items.pop();
            }
            else {
                this.logger.log(SentryLevel.WARNING, "Attempt to pop the root scope.", new Object[0]);
            }
        }
    }
    
    void push(@NotNull final StackItem stackItem) {
        this.items.push(stackItem);
    }
    
    int size() {
        return this.items.size();
    }
    
    static final class StackItem
    {
        private final SentryOptions options;
        @NotNull
        private volatile ISentryClient client;
        @NotNull
        private volatile IScope scope;
        
        StackItem(@NotNull final SentryOptions options, @NotNull final ISentryClient client, @NotNull final IScope scope) {
            this.client = Objects.requireNonNull(client, "ISentryClient is required.");
            this.scope = Objects.requireNonNull(scope, "Scope is required.");
            this.options = Objects.requireNonNull(options, "Options is required");
        }
        
        StackItem(@NotNull final StackItem item) {
            this.options = item.options;
            this.client = item.client;
            this.scope = item.scope.clone();
        }
        
        @NotNull
        public ISentryClient getClient() {
            return this.client;
        }
        
        public void setClient(@NotNull final ISentryClient client) {
            this.client = client;
        }
        
        @NotNull
        public IScope getScope() {
            return this.scope;
        }
        
        @NotNull
        public SentryOptions getOptions() {
            return this.options;
        }
    }
}
