"""Python replacement for the MATLAB splineA.m routine used by the examples."""

from __future__ import annotations

import numpy as np
from scipy.interpolate import CubicSpline


def splineA(xd, yd, xp, endpoint_orders=None, endpoint_values=None):
    """
    Evaluate a cubic spline through the data (xd, yd).

    With no endpoint information, a natural cubic spline is used.
    Calls of the form splineA(xd, yd, xp, [1, 1], [left, right])
    impose the specified first derivatives at the two endpoints.
    """
    xd = np.asarray(xd, dtype=float)
    yd = np.asarray(yd, dtype=float).reshape(-1)
    xp = np.asarray(xp, dtype=float)

    if endpoint_orders is None or endpoint_values is None:
        bc_type = "natural"
    else:
        endpoint_orders = np.asarray(endpoint_orders, dtype=int).reshape(-1)
        endpoint_values = np.asarray(endpoint_values, dtype=float).reshape(-1)
        if endpoint_orders.size != 2 or endpoint_values.size != 2:
            raise ValueError("Two endpoint orders and endpoint values are required.")
        bc_type = (
            (int(endpoint_orders[0]), float(endpoint_values[0])),
            (int(endpoint_orders[1]), float(endpoint_values[1])),
        )

    return CubicSpline(xd, yd, bc_type=bc_type)(xp)
