"""Different implementations of the core XRF fit function.

- `ewoksfluo.xrffit.fit.fast_fit.fit_xrf_spectra`: solve a linear system of equations to fit several spectra.
- `ewoksfluo.xrffit.fit.slow_fit.fit_xrf_spectra`: fit several XRF spectra one-by-one.
- `ewoksfluo.xrffit.fit.fast_fit_native.fit_xrf_spectra`: same as `fast_fit` but using the PyMca batch API for fast fitting.
- `ewoksfluo.xrffit.fit.slow_fit_native.fit_xrf_spectra`: same as `slow_fit` but using the PyMca batch API for slow fitting.
- `ewoksfluo.xrffit.fit.fast_fit_native.fit_xrf_spectra_legacy`: same as `fast_fit_native` but before HDF5 support.
- `ewoksfluo.xrffit.fit.slow_fit_native.fit_xrf_spectra_legacy`: same as `slow_fit_native` but before HDF5 support.

All functions can be called through `ewoksfluo.xrffit.fit.fit_xrf_spectra`.
"""

from typing import Optional

import numpy

from ..pymca_config import PyMcaXrfConfiguration
from . import fast_fit
from . import fast_fit_native
from . import slow_fit
from . import slow_fit_native
from .types import XRFBatchFitResult


def fit_xrf_spectra(
    xrf_spectra: numpy.ndarray,
    configuration: PyMcaXrfConfiguration,
    quantification: Optional[bool] = None,
    individual_weights: Optional[bool] = None,
    live_times: Optional[numpy.ndarray] = None,
    positive_peak_areas: Optional[bool] = None,
    diagnostics: Optional[bool] = None,
    fast_fitting: Optional[bool] = None,
    native_fitting: Optional[bool] = None,
    native_legacy_fitting: Optional[bool] = None,
) -> XRFBatchFitResult:
    """
    :param xrf_spectra: shape `(num_spectra, num_channels)`
    :param configuration: PyMca configuration.
    :param quantification: Calculate mass fractions from peak area's.
    :param individual_weights: When fitting with weights, use the weight of each
                                spectrum (slow) instead of the average weight.
    :param live_times: 1D array with one value for each XRF spectrum.
                       Only used for mass fractions with fundamental parameters.
    :param positive_peak_areas:
    :param diagnostics: fit model and residuals.
    :param fast_fitting: Fast fitting means fit all spectra by solving a single linear system of equations.
    :param native_fitting: Use native PyMca batch processing.
    :param native_legacy_fitting: Use legacy native PyMca batch processing.
    """
    if fast_fitting:
        if native_legacy_fitting:
            _fit = fast_fit_native.fit_xrf_spectra_legacy
        elif native_fitting:
            _fit = fast_fit_native.fit_xrf_spectra
        else:
            _fit = fast_fit.fit_xrf_spectra
    else:
        if native_legacy_fitting:
            _fit = slow_fit_native.fit_xrf_spectra_legacy
        elif native_fitting:
            _fit = slow_fit_native.fit_xrf_spectra
        else:
            _fit = slow_fit.fit_xrf_spectra

    return _fit(
        xrf_spectra,
        configuration,
        quantification=quantification,
        individual_weights=individual_weights,
        live_times=live_times,
        positive_peak_areas=positive_peak_areas,
        diagnostics=diagnostics,
    )
