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

package com.hypixel.hytale.builtin.asseteditor.util;

import org.bson.BsonArray;
import com.hypixel.hytale.common.util.StringUtil;
import org.bson.BsonNull;
import org.bson.BsonValue;
import java.util.function.BiConsumer;
import javax.annotation.Nonnull;
import org.bson.BsonDocument;

public class BsonTransformationUtil
{
    private static void actionOnProperty(final BsonDocument entity, @Nonnull final String[] propertyPath, @Nonnull final BiConsumer<BsonValue, String> biConsumer, final boolean create) {
        BsonValue current = entity;
        for (int i = 0; i < propertyPath.length - 1; ++i) {
            BsonValue jsonElement;
            if (current instanceof final BsonDocument bsonDocument) {
                jsonElement = bsonDocument.get(propertyPath[i]);
                if (jsonElement == null || jsonElement instanceof BsonNull) {
                    if (!create) {
                        return;
                    }
                    if (StringUtil.isNumericString(propertyPath[i + 1])) {
                        jsonElement = new BsonArray();
                    }
                    else {
                        jsonElement = new BsonDocument();
                    }
                    ((BsonDocument)current).put(propertyPath[i], jsonElement);
                }
            }
            else {
                if (!(current instanceof BsonArray) || !StringUtil.isNumericString(propertyPath[i])) {
                    throw new IllegalArgumentException("Element is not Object or (Array or invalid index)! " + String.join(".", (CharSequence[])propertyPath) + ", " + propertyPath[i] + ", " + String.valueOf(current));
                }
                final int index = Integer.parseInt(propertyPath[i]);
                jsonElement = ((BsonArray)current).get(index);
                if (jsonElement == null || jsonElement instanceof BsonNull) {
                    if (!create) {
                        return;
                    }
                    if (StringUtil.isNumericString(propertyPath[i + 1])) {
                        jsonElement = new BsonArray();
                    }
                    else {
                        jsonElement = new BsonDocument();
                    }
                    ((BsonArray)current).set(index, jsonElement);
                }
            }
            current = jsonElement;
        }
        biConsumer.accept(current, propertyPath[propertyPath.length - 1]);
    }
    
    public static void removeProperty(final BsonDocument entity, @Nonnull final String[] propertyPath) {
        actionOnProperty(entity, propertyPath, (parent, key) -> {
            if (parent instanceof final BsonDocument bsonDocument) {
                bsonDocument.remove(key);
            }
            else if (parent instanceof BsonArray && StringUtil.isNumericString(key)) {
                ((BsonArray)parent).remove(Integer.parseInt(key));
            }
            else {
                throw new IllegalArgumentException("Element is not Object or (Array or invalid index)! " + key + ", " + key + ", " + String.valueOf(parent));
            }
        }, false);
    }
    
    public static void setProperty(final BsonDocument entity, @Nonnull final String[] pathElements, final BsonValue value) {
        actionOnProperty(entity, pathElements, (parent, key) -> {
            if (parent instanceof final BsonDocument bsonDocument) {
                bsonDocument.put(key, value);
            }
            else if (parent instanceof BsonArray && StringUtil.isNumericString(key)) {
                ((BsonArray)parent).set(Integer.parseInt(key), value);
            }
            else {
                throw new IllegalArgumentException("Element is not Object or (Array or invalid index)! " + key + ", " + key + ", " + String.valueOf(parent));
            }
        }, true);
    }
    
    public static void insertProperty(final BsonDocument entity, @Nonnull final String[] pathElements, final BsonValue value) {
        actionOnProperty(entity, pathElements, (parent, key) -> {
            if (parent instanceof final BsonDocument bsonDocument) {
                bsonDocument.put(key, value);
            }
            else if (parent instanceof BsonArray && StringUtil.isNumericString(key)) {
                ((BsonArray)parent).add(Integer.parseInt(key), value);
            }
            else {
                throw new IllegalArgumentException("Element is not Object or (Array or invalid index)! " + key + ", " + key + ", " + String.valueOf(parent));
            }
        }, true);
    }
}
