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

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

import javax.annotation.Nullable;
import com.hypixel.hytale.codec.schema.config.NumberSchema;
import com.hypixel.hytale.codec.schema.config.StringSchema;
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 org.bson.BsonDouble;
import com.hypixel.hytale.codec.ExtraInfo;
import javax.annotation.Nonnull;
import org.bson.BsonValue;
import com.hypixel.hytale.codec.PrimitiveCodec;
import com.hypixel.hytale.codec.RawJsonCodec;
import com.hypixel.hytale.codec.Codec;

public class FloatCodec implements Codec<Float>, RawJsonCodec<Float>, PrimitiveCodec
{
    public static final String STRING_SCHEMA_PATTERN = "^(-?Infinity|NaN)$";
    
    @Nonnull
    @Override
    public Float decode(@Nonnull final BsonValue bsonValue, final ExtraInfo extraInfo) {
        return decodeFloat(bsonValue);
    }
    
    @Nonnull
    @Override
    public BsonValue encode(final Float t, final ExtraInfo extraInfo) {
        return new BsonDouble(t);
    }
    
    @Nonnull
    @Override
    public Float decodeJson(@Nonnull final RawJsonReader reader, final ExtraInfo extraInfo) throws IOException {
        return readFloat(reader);
    }
    
    @Nonnull
    @Override
    public Schema toSchema(@Nonnull final SchemaContext context) {
        final StringSchema stringSchema = new StringSchema();
        stringSchema.setPattern("^(-?Infinity|NaN)$");
        return Schema.anyOf(new NumberSchema(), stringSchema);
    }
    
    @Nonnull
    @Override
    public Schema toSchema(@Nonnull final SchemaContext context, @Nullable final Float def) {
        final StringSchema stringSchema = new StringSchema();
        stringSchema.setPattern("^(-?Infinity|NaN)$");
        final NumberSchema numberSchema = new NumberSchema();
        if (def != null) {
            if (def.isNaN() || def.isInfinite()) {
                stringSchema.setDefault(def.toString());
            }
            else {
                numberSchema.setDefault((double)def);
            }
        }
        final Schema schema = Schema.anyOf(numberSchema, stringSchema);
        schema.getHytale().setType("Number");
        return schema;
    }
    
    public static float decodeFloat(@Nonnull final BsonValue value) {
        if (value.isString()) {
            final String value2 = value.asString().getValue();
            switch (value2) {
                case "NaN": {
                    return Float.NaN;
                }
                case "Infinity": {
                    return Float.POSITIVE_INFINITY;
                }
                case "-Infinity": {
                    return Float.NEGATIVE_INFINITY;
                }
            }
        }
        return (float)value.asNumber().doubleValue();
    }
    
    public static float readFloat(@Nonnull final RawJsonReader reader) throws IOException {
        if (reader.peekFor('\"')) {
            final String string;
            final String str = string = reader.readString();
            return switch (string) {
                case "NaN" -> Float.NaN;
                case "Infinity" -> Float.POSITIVE_INFINITY;
                case "-Infinity" -> Float.NEGATIVE_INFINITY;
                default -> throw new IOException("Unexpected string: \"" + str + "\", expected NaN, Infinity, -Infinity");
            };
        }
        return (float)reader.readDoubleValue();
    }
}
