"""
This is the implementation of the OGN node defined in OgnPerturbPoints.ogn
"""
from contextlib import suppress

import numpy as np


class OgnPerturbPointsPy:
    """
    Perturb an array of points by random amounts within a proscribed limit
    """

    @staticmethod
    def compute(db) -> bool:
        """Compute the outputs from the current input"""

        # No points mean nothing to perturb
        point_count = len(db.inputs.points)
        if point_count == 0:
            return True

        range_size = db.inputs.maximum - db.inputs.minimum
        percent_modified = max(0.0, min(100.0, db.inputs.percentModified))
        points_to_modify = int(percent_modified * point_count / 100.0)

        # Steal the input to modify directly as output
        db.move(db.attributes.outputs.points, db.attributes.inputs.points)

        db.outputs.points[0:points_to_modify] = (
            db.outputs.points[0:points_to_modify]
            + range_size * np.random.random_sample((points_to_modify, 3))
            + db.inputs.minimum
        )

        # If the dynamic inputs and outputs exist then they will steal data
        with suppress(AttributeError):
            db.move(db.attributes.outputs.stolen, db.attributes.inputs.stealMe)

        return True
