#!/usr/bin/env python3
# Helpore study of full time parents' cooking, cleaning and laundry, Switzerland 2024: adds up three tasks from the Federal Statistical Office extract in raw/.
import csv
import hashlib
import json
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parent
SOURCE = ROOT / "raw" / "bfs-fulltime-parents-2024.csv"
# The official link can return the same rows in another order, so the file is checked by its content: the sha256 of
# its rows as JSON arrays, the header first and the data rows sorted, joined by newlines (line endings and byte
# order mark do not count). The byte sha256 of the file this study used is printed for information only.
EXPECTED_ROWS_SHA256 = "2a986a220a875ba2ebfd1d5be66360cbea3606a6fa29fef69eefd5b830d2614d"
STUDY_FILE_SHA256 = "f095eac3320390b8e46fc9d11b6ac7ccb2f8920739b2fa8c888e15d26c3aa05b"
OFFICIAL_URL = "https://disseminate.stats.swiss/rest/data/CH1.SAKE_MOD_UA,DF_SAKE_MOD_UA_3_WITHCHILD,1.0.0/2024.HFA.POP_GE15.2050.Y0T14.._T.111.?dimensionAtObservation=AllDimensions"
ACCEPT = "application/vnd.sdmx.data+csv;version=2.0;labels=both"

if not SOURCE.is_file():
    sys.exit(
        "The Federal Statistical Office extract is not included with this script.\n"
        f"Download it from {OFFICIAL_URL}\n"
        f"with the request header Accept: {ACCEPT}\n"
        f"and save it unchanged as {SOURCE.relative_to(ROOT)} in the folder that holds this script.\n"
        f"Expected rows sha256: {EXPECTED_ROWS_SHA256}"
    )

raw = SOURCE.read_bytes()
table = list(csv.reader(raw.decode("utf-8-sig").splitlines()))
canonical = "\n".join(
    [json.dumps(table[0], ensure_ascii=False)] + sorted(json.dumps(cells, ensure_ascii=False) for cells in table[1:] if cells)
)
if hashlib.sha256(canonical.encode("utf-8")).hexdigest() != EXPECTED_ROWS_SHA256:
    sys.exit(f"{SOURCE.relative_to(ROOT)} differs from the extract this study used (expected rows sha256 {EXPECTED_ROWS_SHA256})")
rows = list(csv.DictReader(raw.decode("utf-8-sig").splitlines()))

expected_dimensions = {
    "DIFF_YEAR: Year": "2024: 2024",
    "WORK_TYPES: Unpaid and paid work": "HFA: Domestic and family workload",
    "REFPOP_SAKE: Reference population": "POP_GE15: Total population",
    "FAMILYSIT_MODUA: Family situation": "2050: Person with child(ren) under 25",
    "AGE_YGSTCHILD: Age of youngest child": "Y0T14: 0-14 years",
    "AGE: Age": "_T: Total",
    "WORKSIT_MODUA: Work situation": "111: Full-time: 90-100%",
}
assert len(rows) == 39
for row in rows:
    for key, value in expected_dimensions.items():
        assert row[key] == value, (key, row[key])
    assert row["OBS_STATUS: Observation Status"] == "A: Normal value"

def observation(sex, activity):
    matches = [
        row for row in rows
        if row["SEX: Gender"] == sex
        and row["UNPAID_ACTIVITY: Type of activity"] == activity
    ]
    assert len(matches) == 1, (sex, activity, len(matches))
    return float(matches[0]["OBS_VALUE"])

female = "2: Feminine"
male = "1: Masculine"
activities = ["MAHL", "PUTZ", "WASCH"]
female_three = sum(observation(female, activity) for activity in activities)
male_three = sum(observation(male, activity) for activity in activities)
three_gap = female_three - male_three
overall_gap = observation(female, "_T") - observation(male, "_T")

result = {
    "sourceRowsSha256": EXPECTED_ROWS_SHA256,
    "sourceFileSha256": hashlib.sha256(raw).hexdigest(),
    "studyFileSha256": STUDY_FILE_SHA256,
    "rowCount": len(rows),
    "allObservationStatuses": sorted({row["OBS_STATUS: Observation Status"] for row in rows}),
    "femaleThreeTasksHours": female_three,
    "maleThreeTasksHours": male_three,
    "threeTaskGapHours": three_gap,
    "femaleOverallHours": observation(female, "_T"),
    "maleOverallHours": observation(male, "_T"),
    "overallGapHours": overall_gap,
    "threeTaskShareOfNetOverallGapPercent": three_gap / overall_gap * 100,
}
print(json.dumps(result, indent=2, sort_keys=True))
