"""
Unit tests for server/nepal_calendar.py — the accurate AD<->BS date service.

Run with: cd server && ../venv/bin/python3 -m unittest tests.test_nepal_calendar -v
"""
import os
import sys
import unittest

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import nepal_calendar as nc  # noqa: E402


class BsFromAdTests(unittest.TestCase):
    def test_known_nepali_new_year(self):
        # Baishakh 1 has fallen on 14 April in recent years — a well-known
        # public reference point, unlike an arbitrary mid-year date.
        self.assertEqual(nc.bs_approx("2023-04-14")["label"], "2080-01-01")

    def test_regression_reference_date(self):
        self.assertEqual(nc.bs_approx("2026-08-29")["label"], "2083-05-13")

    def test_month_name_matches_index(self):
        bs = nc.bs_approx("2026-08-29")
        self.assertEqual(bs["month_name"], nc.NEPALI_MONTHS_CALENDAR[bs["month"] - 1])

    def test_out_of_range_raises(self):
        with self.assertRaises(ValueError):
            nc.bs_approx("1800-01-01")


class AdFromBsTests(unittest.TestCase):
    def test_round_trip(self):
        ad = nc.bs_to_ad_approx(2083, 5, 13)
        self.assertEqual(ad, "2026-08-29")
        self.assertEqual(nc.bs_approx(ad)["label"], "2083-05-13")

    def test_rejects_day_beyond_real_month_length(self):
        # Poush 2080 (BS month 9) has 29 days per the official reference
        # table — day 30 must not silently roll over into Magh.
        with self.assertRaises(ValueError):
            nc.bs_to_ad_approx(2080, 9, 30)

    def test_variable_month_length_is_not_fixed_thirty(self):
        # The whole point of this module: month lengths genuinely vary.
        # Baishakh 2080 has 31 days; Poush 2080 has 29. A "fixed 30 days"
        # implementation would get both wrong in opposite directions.
        self.assertEqual(nc.bs_to_ad_approx(2080, 1, 31), "2023-05-14")
        with self.assertRaises(ValueError):
            nc.bs_to_ad_approx(2080, 1, 32)


class FyLabelTests(unittest.TestCase):
    def test_uses_fiscal_year_row_when_covered(self):
        fys = [{"label_bs": "2082-83", "start_ad": "2025-07-16", "end_ad": "2026-07-15"}]
        self.assertEqual(nc.fy_label_for_ad("2025-12-01", fys), "2082-83")

    def test_falls_back_to_calendar_derivation_shrawan_onward(self):
        # No fiscal_year rows at all: derive from the real BS month. Shrawan
        # (BS month 4) is the first month of a new Nepali fiscal year.
        self.assertEqual(nc.fy_label_for_ad("2026-08-29"), "2083-84")

    def test_falls_back_to_calendar_derivation_before_shrawan(self):
        self.assertEqual(nc.fy_label_for_ad("2026-05-01"), "2082-83")


if __name__ == "__main__":
    unittest.main()
