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

package com.hypixel.hytale.codec.codecs.map;

import com.hypixel.hytale.codec.schema.config.NumberSchema;
import com.hypixel.hytale.codec.schema.config.StringSchema;
import com.hypixel.hytale.codec.schema.config.ObjectSchema;
import com.hypixel.hytale.codec.schema.config.Schema;
import com.hypixel.hytale.codec.schema.SchemaContext;
import java.io.IOException;
import com.hypixel.hytale.codec.util.RawJsonReader;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import org.bson.BsonDouble;
import java.util.Iterator;
import org.bson.BsonDocument;
import it.unimi.dsi.fastutil.objects.Object2FloatMaps;
import org.bson.BsonString;
import java.util.Map;
import com.hypixel.hytale.codec.ExtraInfo;
import javax.annotation.Nonnull;
import org.bson.BsonValue;
import java.util.function.Supplier;
import com.hypixel.hytale.codec.WrappedCodec;
import it.unimi.dsi.fastutil.objects.Object2FloatMap;
import com.hypixel.hytale.codec.Codec;

public class Object2FloatMapCodec<T> implements Codec<Object2FloatMap<T>>, WrappedCodec<T>
{
    private final Codec<T> keyCodec;
    private final Supplier<Object2FloatMap<T>> supplier;
    private final boolean unmodifiable;
    
    public Object2FloatMapCodec(final Codec<T> keyCodec, final Supplier<Object2FloatMap<T>> supplier, final boolean unmodifiable) {
        this.keyCodec = keyCodec;
        this.supplier = supplier;
        this.unmodifiable = unmodifiable;
    }
    
    public Object2FloatMapCodec(final Codec<T> keyCodec, final Supplier<Object2FloatMap<T>> supplier) {
        this(keyCodec, supplier, true);
    }
    
    @Override
    public Codec<T> getChildCodec() {
        return this.keyCodec;
    }
    
    @Override
    public Object2FloatMap<T> decode(@Nonnull final BsonValue bsonValue, final ExtraInfo extraInfo) {
        final BsonDocument bsonDocument = bsonValue.asDocument();
        Object2FloatMap<T> map = this.supplier.get();
        for (final Map.Entry<String, BsonValue> stringBsonValueEntry : bsonDocument.entrySet()) {
            final T decodedKey = this.keyCodec.decode(new BsonString(stringBsonValueEntry.getKey()), extraInfo);
            map.put(decodedKey, (float)stringBsonValueEntry.getValue().asNumber().doubleValue());
        }
        if (this.unmodifiable) {
            map = Object2FloatMaps.unmodifiable((Object2FloatMap<? extends T>)map);
        }
        return map;
    }
    
    @Nonnull
    @Override
    public BsonValue encode(@Nonnull final Object2FloatMap<T> map, final ExtraInfo extraInfo) {
        final BsonDocument bsonDocument = new BsonDocument();
        for (final T key : map.keySet()) {
            final String encodedKey = this.keyCodec.encode(key, extraInfo).asString().getValue();
            bsonDocument.put(encodedKey, new BsonDouble(map.getFloat(key)));
        }
        return bsonDocument;
    }
    
    @Override
    public Object2FloatMap<T> decodeJson(@Nonnull final RawJsonReader reader, final ExtraInfo extraInfo) throws IOException {
        reader.expect('{');
        reader.consumeWhiteSpace();
        Object2FloatMap<T> map = this.supplier.get();
        if (reader.tryConsume('}')) {
            if (this.unmodifiable) {
                map = Object2FloatMaps.unmodifiable((Object2FloatMap<? extends T>)map);
            }
            return map;
        }
        while (true) {
            final T key = this.keyCodec.decodeJson(reader, extraInfo);
            reader.consumeWhiteSpace();
            reader.expect(':');
            reader.consumeWhiteSpace();
            map.put(key, reader.readFloatValue());
            reader.consumeWhiteSpace();
            if (reader.tryConsumeOrExpect('}', ',')) {
                break;
            }
            reader.consumeWhiteSpace();
        }
        if (this.unmodifiable) {
            map = Object2FloatMaps.unmodifiable((Object2FloatMap<? extends T>)map);
        }
        return map;
    }
    
    @Nonnull
    @Override
    public Schema toSchema(@Nonnull final SchemaContext context) {
        final ObjectSchema s = new ObjectSchema();
        final StringSchema key = (StringSchema)this.keyCodec.toSchema(context);
        String title = key.getTitle();
        if (title == null) {
            title = key.getHytale().getType();
        }
        s.setTitle("Map of " + title + " to float");
        s.setPropertyNames(key);
        s.setAdditionalProperties(new NumberSchema());
        return s;
    }
}
