#!/usr/bin/env python3
"""
Water-purification add-on modules for the camp unit.
1) Biological: thermal (pasteurize/boil) vs chemical (chlorine) vs UV-C
2) Fluoride removal (activated alumina / bone char) vs arsenic (iron oxide)
3) On-site chlorine generation by brine electrolysis (electrochlorination)

Chemistry anchors:
- Pasteurization: 65 C for ~6 min kills bacteria/viruses/protozoa (WAPI std).
  Heat 25->70 C = 45 K * 4.186 kJ = 188 kJ/L; counterflow HX recovers ~80%.
- Chlorination dose: 2 mg/L clear water (5 mg/L turbid); CT >= 30 min.
- Electrochlorination: brine electrolysis -> NaOCl. Field devices (WATA-class):
  ~4.5 Wh and ~4 g NaCl per g active chlorine; MMO-Ti electrodes last years.
- Fluoride: activated alumina eff. capacity ~1.5 mg F/g (regenerable);
  bone char ~2 mg F/g (charrable on-site). Iron oxide does NOT bind F well.
- Arsenic: granular ferric hydroxide (FeOOH) eff. ~1 mg As/g field;
  As(III) must be oxidized to As(V) first -> chlorine pre-ox synergy.
"""

DRINK_L_DAY = 20          # drinking + cooking, family of 5
SOLAR = 5.5 * 0.78
PV_W, BATT = 0.45, 160.0

# ---------- 1) biological disinfection routes, energy per liter ----------
def bio_routes():
    boil = 45 * 4.186 / 3600 / 0.85 * 1000            # Wh/L, 85% induction eff, no HX (rolling boil ~+15%)
    boil *= 1.15
    past_hx = 45 * 4.186 / 3600 / 0.85 * (1 - 0.80) * 1000
    uv = 2.0                                           # Wh/L incl. pump, clear water only (<5 NTU)
    cl = 2e-3 * 4.5                                    # 2 mg/L * 4.5 Wh/g = 0.009 Wh/L
    return [("Chlorine (2 mg/L dose)", cl, "residual protects stored water; taste; needs CT 30 min"),
            ("UV-C flow cell", uv, "no residual; blocked by turbidity >5 NTU"),
            ("Induction pasteurizer + 80% HX", past_hx, "works on turbid water; no residual"),
            ("Rolling boil on induction", boil, "the fallback; works on anything")]

# ---------- 2) contaminant removal media budgets ----------
def media_budget(c_in, c_target, cap_mg_g, L_day=DRINK_L_DAY):
    remove_mg_day = (c_in - c_target) * L_day
    g_day = remove_mg_day / cap_mg_g
    return remove_mg_day, g_day, g_day * 365 / 1000   # kg/yr

def contaminants():
    rows = []
    # Fluoride: Rift Valley / S.Asia wells 5-15 mg/L, WHO limit 1.5
    for name, cin, cap, cost_kg in [
        ("F: activated alumina (8->1.5 mg/L)", 8.0, 1.5, 3.0),
        ("F: bone char, on-site (8->1.5)",     8.0, 2.0, 0.8)]:
        _, g_day, kg_yr = media_budget(cin, 1.5 if 'alumina' in name else 1.5, cap)
        rows.append((name, g_day, kg_yr, kg_yr * cost_kg))
    # Arsenic: Bengal-basin wells 0.1-0.5 mg/L, WHO 0.01
    _, g_day, kg_yr = media_budget(0.25, 0.01, 1.0)
    rows.append(("As: iron-oxide media (250->10 ug/L)", g_day, kg_yr, kg_yr * 6.0))
    return rows

# fix the fluoride call (cap differs): recompute cleanly
def contaminants2():
    out = []
    for name, cin, ctgt, cap, costkg in [
        ("Fluoride - activated alumina", 8.0, 1.5, 1.5, 3.0),
        ("Fluoride - bone char (on-site)", 8.0, 1.5, 2.0, 0.8),
        ("Arsenic - iron-oxide (FeOOH)", 0.25, 0.01, 1.0, 6.0)]:
        mg_day, g_day, kg_yr = media_budget(cin, ctgt, cap)
        out.append(dict(name=name, mg_day=mg_day, g_day=round(g_day, 1),
                        kg_yr=round(kg_yr, 1), usd_yr=round(kg_yr * costkg, 0)))
    return out

# ---------- 3) electrochlorination sizing ----------
def chlorinator(scope, people, Lpd, dose_mg_L, cell_cost):
    L_day = people * Lpd
    g_cl_day = L_day * dose_mg_L / 1000
    wh_day = g_cl_day * 4.5
    salt_g_day = g_cl_day * 4.0
    pv_share = wh_day / 1000 * 1000 / SOLAR * PV_W
    return dict(scope=scope, L_day=L_day, g_cl=round(g_cl_day, 1),
                wh=round(wh_day, 1), salt_kg_yr=round(salt_g_day * 365 / 1000, 1),
                capex=round(cell_cost + pv_share),
                salt_usd_yr=round(salt_g_day * 365 / 1000 * 0.5, 1))  # $0.5/kg salt

if __name__ == '__main__':
    print("1) BIOLOGICAL DISINFECTION - energy per liter (family 20 L/day drinking)")
    for n, wh, note in bio_routes():
        print(f"   {n:<34}{wh:>8.3f} Wh/L   {note}")
    print(f"   (MOF air-harvest, for scale:      620.000 Wh/L)")

    print("\n2) CONTAMINANT MEDIA BUDGET - 20 L/day treated")
    for r in contaminants2():
        print(f"   {r['name']:<32}{r['g_day']:>6} g/day  {r['kg_yr']:>5} kg/yr  ~${r['usd_yr']:.0f}/yr media")

    print("\n3) ELECTROCHLORINATION (4.5 Wh + 4 g salt per g Cl)")
    for c in [chlorinator("Household batch (5 p)", 5, 4, 2.0, 90),
              chlorinator("Cluster kiosk (25 p)", 25, 15, 2.0, 180),
              chlorinator("Camp plant (10,000 p)", 10000, 15, 2.0, 2500)]:
        print(f"   {c['scope']:<24}{c['L_day']:>7} L/d  {c['g_cl']:>6} g Cl/d  {c['wh']:>7} Wh/d  "
              f"salt {c['salt_kg_yr']} kg/yr (${c['salt_usd_yr']}/yr)  capex ~${c['capex']}")

    print("\nPasteurizer capex: coil-pot + counterflow HX + WAPI thermostat ~ $70-120")
    print("Arsenic note: chlorine pre-oxidation As(III)->As(V) boosts FeOOH capture;")
    print("spent As media is hazardous - stabilize (concrete) or return-to-supplier.")
