# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""
Tests for IRAFStarFinder.
"""

import itertools
import os.path as op

from astropy.table import Table
from astropy.tests.helper import catch_warnings
import numpy as np
from numpy.testing import assert_allclose
import pytest

from ..irafstarfinder import IRAFStarFinder
from ...datasets import make_100gaussians_image
from ...utils.exceptions import NoDetectionsWarning
from ...utils._optional_deps import HAS_SCIPY  # noqa


DATA = make_100gaussians_image()
THRESHOLDS = [8.0, 10.0]
FWHMS = [1.0, 1.5, 2.0]


@pytest.mark.skipif('not HAS_SCIPY')
class TestIRAFStarFinder:
    @pytest.mark.parametrize(('threshold', 'fwhm'),
                             list(itertools.product(THRESHOLDS, FWHMS)))
    def test_irafstarfind(self, threshold, fwhm):
        starfinder = IRAFStarFinder(threshold, fwhm, sigma_radius=1.5)
        tbl = starfinder(DATA)
        datafn = (f'irafstarfind_test_thresh{threshold:04.1f}_'
                  f'fwhm{fwhm:04.1f}.txt')
        datafn = op.join(op.dirname(op.abspath(__file__)), 'data', datafn)
        tbl_ref = Table.read(datafn, format='ascii')

        assert tbl.colnames == tbl_ref.colnames
        for col in tbl.colnames:
            assert_allclose(tbl[col], tbl_ref[col])

    def test_irafstarfind_threshold_fwhm_inputs(self):
        with pytest.raises(TypeError):
            IRAFStarFinder(threshold=np.ones((2, 2)), fwhm=3.)

        with pytest.raises(TypeError):
            IRAFStarFinder(threshold=3., fwhm=np.ones((2, 2)))

    def test_irafstarfind_nosources(self):
        data = np.ones((3, 3))
        with catch_warnings(NoDetectionsWarning) as warning_lines:
            starfinder = IRAFStarFinder(threshold=10, fwhm=1)
            tbl = starfinder(data)
            assert tbl is None
            assert 'No sources were found.' in str(warning_lines[0].message)

    def test_irafstarfind_sharpness(self):
        """Sources found, but none pass the sharpness criteria."""
        with catch_warnings(NoDetectionsWarning) as warning_lines:
            starfinder = IRAFStarFinder(threshold=50, fwhm=1.0, sharplo=2.)
            tbl = starfinder(DATA)
            assert tbl is None
            assert ('Sources were found, but none pass the sharpness and '
                    'roundness criteria.' in str(warning_lines[0].message))

    def test_irafstarfind_roundness(self):
        """Sources found, but none pass the roundness criteria."""
        with catch_warnings(NoDetectionsWarning) as warning_lines:
            starfinder = IRAFStarFinder(threshold=50, fwhm=1.0, roundlo=1.)
            tbl = starfinder(DATA)
            assert tbl is None
            assert ('Sources were found, but none pass the sharpness and '
                    'roundness criteria.' in str(warning_lines[0].message))

    def test_irafstarfind_sky(self):
        starfinder = IRAFStarFinder(threshold=25.0, fwhm=2.0, sky=10.)
        tbl = starfinder(DATA)
        assert len(tbl) == 4

    def test_irafstarfind_largesky(self):
        with catch_warnings(NoDetectionsWarning) as warning_lines:
            starfinder = IRAFStarFinder(threshold=25.0, fwhm=2.0, sky=100.)
            tbl = starfinder(DATA)
            assert tbl is None
            assert ('Sources were found, but none pass the sharpness and '
                    'roundness criteria.' in str(warning_lines[0].message))

    def test_irafstarfind_peakmax_filtering(self):
        """
        Regression test that objects with ``peak`` >= ``peakmax`` are
        filtered out.
        """
        peakmax = 20
        starfinder = IRAFStarFinder(threshold=7., fwhm=2, roundlo=-np.inf,
                                    roundhi=np.inf, sharplo=-np.inf,
                                    sharphi=np.inf, peakmax=peakmax)
        tbl = starfinder(DATA)
        assert len(tbl) == 117
        assert all(tbl['peak'] < peakmax)

    def test_irafstarfind_brightest_filtering(self):
        """
        Regression test that only top ``brightest`` objects are selected.
        """
        brightest = 40
        starfinder = IRAFStarFinder(threshold=7., fwhm=2, roundlo=-np.inf,
                                    roundhi=np.inf, sharplo=-np.inf,
                                    sharphi=np.inf, brightest=brightest)
        tbl = starfinder(DATA)
        assert len(tbl) == brightest

    def test_irafstarfind_mask(self):
        """Test IRAFStarFinder with a mask."""

        starfinder = IRAFStarFinder(threshold=10, fwhm=1.5)
        mask = np.zeros(DATA.shape, dtype=bool)
        mask[100:200] = True
        tbl1 = starfinder(DATA)
        tbl2 = starfinder(DATA, mask=mask)
        assert len(tbl1) > len(tbl2)

@@ -2266,73 +2266,32 @@
 pass
- the sharpness and '%0A                    'roundness criteria.' in
+' in%0A                   
  str
@@ -2696,73 +2696,458 @@
 pass
- the sharpness and '%0A                    'roundness criteria.' in
+' in%0A                    str(warning_lines%5B0%5D.message))%0A%0A    def test_irafstarfind_peakmax(self):%0A        %22%22%22Sources found, but none pass the peakmax criteria.%22%22%22%0A        with catch_warnings(NoDetectionsWarning) as warning_lines:%0A            starfinder = IRAFStarFinder(threshold=50, fwhm=1.0, peakmax=1.)%0A            tbl = starfinder(DATA)%0A            assert tbl is None%0A            assert ('Sources were found, but none pass' in%0A                   
  str
@@ -3653,73 +3653,32 @@
 pass
- the sharpness and '%0A                    'roundness criteria.' in
+' in%0A                   
  str

Update IRAFStarFinder tests