package mhtree;

import cz.muni.fi.disa.similarityoperators.cover.AbstractRepresentation.PrecomputedDistances;
import messif.buckets.BucketStorageException;
import messif.buckets.LocalBucket;
import messif.objects.LocalAbstractObject;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * Represents a leaf node in MH-Tree.
 */

public class LeafNode extends Node implements Serializable {

    /**
     * Serialization ID
     */
    private static final long serialVersionUID = 1L;

    /**
     * Bucket for storing objects of the MH-Tree.
     */
    private final LocalBucket bucket;

    protected LeafNode(PrecomputedDistances distances, LocalBucket bucket, InsertType insertType, ObjectToNodeDistance objectToNodeDistance) throws BucketStorageException {
        super(distances, insertType, objectToNodeDistance);

        this.bucket = bucket;
        this.bucket.addObjects(distances.getObjects());
    }

    /**
     * Returns the number of objects stored in node's bucket.
     *
     * @return the number of objects stored in node's bucket
     */
    protected int getObjectCount() {
        return bucket.getObjectCount();
    }

    public LocalBucket getBucket() {
        return bucket;
    }

    @Override
    protected void addObject(LocalAbstractObject object) throws BucketStorageException {
        bucket.addObject(object);
        addObjectIntoHull(object);
    }

    @Override
    public List<LocalAbstractObject> getObjects() {
        List<LocalAbstractObject> objects = new ArrayList<>(bucket.getObjectCount());

        bucket
                .getAllObjects()
                .forEachRemaining(objects::add);

        return objects;
    }

    @Override
    protected int getHeight() {
        return 1;
    }

    @Override
    protected void gatherNodes(List<Node> nodes) {
        nodes.add(this);
    }

    @Override
    protected void gatherLeafNodes(List<LeafNode> leafNodes) {
        leafNodes.add(this);
    }
}
