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

package com.nimbusds.jose.shaded.gson.internal.bind;

import java.util.Objects;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.IOException;
import com.nimbusds.jose.shaded.gson.JsonArray;
import com.nimbusds.jose.shaded.gson.JsonObject;
import com.nimbusds.jose.shaded.gson.JsonNull;
import java.util.ArrayList;
import com.nimbusds.jose.shaded.gson.JsonElement;
import java.util.List;
import com.nimbusds.jose.shaded.gson.JsonPrimitive;
import java.io.Writer;
import com.nimbusds.jose.shaded.gson.stream.JsonWriter;

public final class JsonTreeWriter extends JsonWriter
{
    private static final Writer UNWRITABLE_WRITER;
    private static final JsonPrimitive SENTINEL_CLOSED;
    private final List<JsonElement> stack;
    private String pendingName;
    private JsonElement product;
    
    public JsonTreeWriter() {
        super(JsonTreeWriter.UNWRITABLE_WRITER);
        this.stack = new ArrayList<JsonElement>();
        this.product = JsonNull.INSTANCE;
    }
    
    public JsonElement get() {
        if (!this.stack.isEmpty()) {
            throw new IllegalStateException("Expected one JSON element but was " + this.stack);
        }
        return this.product;
    }
    
    private JsonElement peek() {
        return this.stack.get(this.stack.size() - 1);
    }
    
    private void put(final JsonElement value) {
        if (this.pendingName != null) {
            if (!value.isJsonNull() || this.getSerializeNulls()) {
                final JsonObject object = (JsonObject)this.peek();
                object.add(this.pendingName, value);
            }
            this.pendingName = null;
        }
        else if (this.stack.isEmpty()) {
            this.product = value;
        }
        else {
            final JsonElement element = this.peek();
            if (!(element instanceof JsonArray)) {
                throw new IllegalStateException();
            }
            ((JsonArray)element).add(value);
        }
    }
    
    @CanIgnoreReturnValue
    @Override
    public JsonWriter beginArray() throws IOException {
        final JsonArray array = new JsonArray();
        this.put(array);
        this.stack.add(array);
        return this;
    }
    
    @CanIgnoreReturnValue
    @Override
    public JsonWriter endArray() throws IOException {
        if (this.stack.isEmpty() || this.pendingName != null) {
            throw new IllegalStateException();
        }
        final JsonElement element = this.peek();
        if (element instanceof JsonArray) {
            this.stack.remove(this.stack.size() - 1);
            return this;
        }
        throw new IllegalStateException();
    }
    
    @CanIgnoreReturnValue
    @Override
    public JsonWriter beginObject() throws IOException {
        final JsonObject object = new JsonObject();
        this.put(object);
        this.stack.add(object);
        return this;
    }
    
    @CanIgnoreReturnValue
    @Override
    public JsonWriter endObject() throws IOException {
        if (this.stack.isEmpty() || this.pendingName != null) {
            throw new IllegalStateException();
        }
        final JsonElement element = this.peek();
        if (element instanceof JsonObject) {
            this.stack.remove(this.stack.size() - 1);
            return this;
        }
        throw new IllegalStateException();
    }
    
    @CanIgnoreReturnValue
    @Override
    public JsonWriter name(final String name) throws IOException {
        Objects.requireNonNull(name, "name == null");
        if (this.stack.isEmpty() || this.pendingName != null) {
            throw new IllegalStateException("Did not expect a name");
        }
        final JsonElement element = this.peek();
        if (element instanceof JsonObject) {
            this.pendingName = name;
            return this;
        }
        throw new IllegalStateException("Please begin an object before writing a name.");
    }
    
    @CanIgnoreReturnValue
    @Override
    public JsonWriter value(final String value) throws IOException {
        if (value == null) {
            return this.nullValue();
        }
        this.put(new JsonPrimitive(value));
        return this;
    }
    
    @CanIgnoreReturnValue
    @Override
    public JsonWriter value(final boolean value) throws IOException {
        this.put(new JsonPrimitive(value));
        return this;
    }
    
    @CanIgnoreReturnValue
    @Override
    public JsonWriter value(final Boolean value) throws IOException {
        if (value == null) {
            return this.nullValue();
        }
        this.put(new JsonPrimitive(value));
        return this;
    }
    
    @CanIgnoreReturnValue
    @Override
    public JsonWriter value(final float value) throws IOException {
        if (!this.isLenient() && (Float.isNaN(value) || Float.isInfinite(value))) {
            throw new IllegalArgumentException("JSON forbids NaN and infinities: " + value);
        }
        this.put(new JsonPrimitive(value));
        return this;
    }
    
    @CanIgnoreReturnValue
    @Override
    public JsonWriter value(final double value) throws IOException {
        if (!this.isLenient() && (Double.isNaN(value) || Double.isInfinite(value))) {
            throw new IllegalArgumentException("JSON forbids NaN and infinities: " + value);
        }
        this.put(new JsonPrimitive(value));
        return this;
    }
    
    @CanIgnoreReturnValue
    @Override
    public JsonWriter value(final long value) throws IOException {
        this.put(new JsonPrimitive(value));
        return this;
    }
    
    @CanIgnoreReturnValue
    @Override
    public JsonWriter value(final Number value) throws IOException {
        if (value == null) {
            return this.nullValue();
        }
        if (!this.isLenient()) {
            final double d = value.doubleValue();
            if (Double.isNaN(d) || Double.isInfinite(d)) {
                throw new IllegalArgumentException("JSON forbids NaN and infinities: " + value);
            }
        }
        this.put(new JsonPrimitive(value));
        return this;
    }
    
    @CanIgnoreReturnValue
    @Override
    public JsonWriter nullValue() throws IOException {
        this.put(JsonNull.INSTANCE);
        return this;
    }
    
    @Override
    public JsonWriter jsonValue(final String value) throws IOException {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public void flush() throws IOException {
    }
    
    @Override
    public void close() throws IOException {
        if (!this.stack.isEmpty()) {
            throw new IOException("Incomplete document");
        }
        this.stack.add(JsonTreeWriter.SENTINEL_CLOSED);
    }
    
    static {
        UNWRITABLE_WRITER = new Writer() {
            @Override
            public void write(final char[] buffer, final int offset, final int counter) {
                throw new AssertionError();
            }
            
            @Override
            public void flush() {
                throw new AssertionError();
            }
            
            @Override
            public void close() {
                throw new AssertionError();
            }
        };
        SENTINEL_CLOSED = new JsonPrimitive("closed");
    }
}
