#!/usr/bin/env python3
"""Anonymised demo consignees across Europe from two production samples (never committed, deleted
after use):
  names.txt  – one "First Last" per line (sampled in RANDOM order so initials are mixed)
  locs.txt   – "street no|postal|city|c_country_id" per line
First names, last names, street names, house numbers and postal/city/country triples are drawn
independently, so no output row is a real customer or a real address. Countries without a
production sample get built-in city/postal/street pools. Country mix is forced to a European
spread (iDempiere C_Country ids of the LogShip instance).
  build-consignees.py names.txt locs.txt out.json [count]
"""
import json, random, re, sys
from collections import Counter

names, locs, out = sys.argv[1], sys.argv[2], sys.argv[3]
N = int(sys.argv[4]) if len(sys.argv) > 4 else 200
random.seed(20261023 + N)

first, last = [], []
for l in open(names, encoding="utf-8"):
    p = l.strip().split()
    if len(p) >= 2: first.append(p[0]); last.append(p[-1])
random.shuffle(first); random.shuffle(last)

streets, places = {}, {}
for l in open(locs, encoding="utf-8"):
    a = l.rstrip("\n").split("|")
    if len(a) < 4: continue
    st = re.sub(r"\s*\d+\s*[a-zA-Z]?(\s*[-/]\s*\d+\w?)?\s*$", "", a[0]).strip()
    if 3 < len(st) < 40 and not re.search(r"\d", st): streets.setdefault(a[3], []).append(st)
    city = a[2].strip().title()
    if a[1].strip() and 2 < len(city) < 30: places.setdefault(a[3], []).append((a[1].strip(), city))

# built-in pools for countries with no/few production samples: (country id, [(postal, city)], [streets], tld)
BUILTIN = {
    "167": ([("2100", "København Ø"), ("8000", "Aarhus C"), ("5000", "Odense C"), ("9000", "Aalborg"), ("2800", "Kongens Lyngby")], ["Østerbrogade", "Nørregade", "Vesterbrogade", "Strandvejen", "Jernbanegade", "Søndergade"], "dk"),
    "313": ([("11456", "Stockholm"), ("41118", "Göteborg"), ("21122", "Malmö"), ("75310", "Uppsala"), ("58222", "Linköping")], ["Drottninggatan", "Kungsgatan", "Storgatan", "Vasagatan", "Linnégatan", "Järnvägsgatan"], "se"),
    "181": ([("00100", "Helsinki"), ("33100", "Tampere"), ("20100", "Turku"), ("90100", "Oulu")], ["Mannerheimintie", "Hämeenkatu", "Kauppakatu", "Rantakatu", "Koulukatu"], "fi"),
    "269": ([("0150", "Oslo"), ("5003", "Bergen"), ("7010", "Trondheim"), ("4006", "Stavanger")], ["Karl Johans gate", "Storgata", "Kirkegata", "Strandgaten", "Bryggen"], "no"),
    "280": ([("00-001", "Warszawa"), ("30-001", "Kraków"), ("50-001", "Wrocław"), ("61-001", "Poznań"), ("80-001", "Gdańsk")], ["ul. Marszałkowska", "ul. Długa", "ul. Piotrkowska", "ul. Krakowska", "ul. Floriańska"], "pl"),
    "166": ([("110 00", "Praha 1"), ("602 00", "Brno"), ("702 00", "Ostrava"), ("301 00", "Plzeň")], ["Václavské náměstí", "Vodičkova", "Masarykova", "Nádražní", "Jiráskova"], "cz"),
    "206": ([("1051", "Budapest"), ("4024", "Debrecen"), ("6720", "Szeged"), ("9021", "Győr")], ["Váci utca", "Andrássy út", "Piac utca", "Kossuth Lajos utca", "Petőfi utca"], "hu"),
    "281": ([("1000-001", "Lisboa"), ("4000-001", "Porto"), ("3000-001", "Coimbra"), ("8000-001", "Faro")], ["Rua Augusta", "Avenida da Liberdade", "Rua de Santa Catarina", "Rua do Comércio", "Rua Direita"], "pt"),
    "212": ([("D02 X285", "Dublin 2"), ("T12 Y8Y7", "Cork"), ("H91 E2K3", "Galway"), ("V94 T2N1", "Limerick")], ["Grafton Street", "O'Connell Street", "Patrick Street", "Shop Street", "Main Street"], "ie"),
    "192": ([("105 57", "Athina"), ("546 24", "Thessaloniki"), ("262 21", "Patra"), ("712 02", "Heraklion")], ["Ermou", "Egnatia", "Panepistimiou", "Tsimiski", "Kifisias"], "gr"),
    "285": ([("010011", "București"), ("400001", "Cluj-Napoca"), ("300001", "Timișoara"), ("700001", "Iași")], ["Strada Lipscani", "Bulevardul Unirii", "Calea Victoriei", "Strada Republicii"], "ro"),
    "107": ([("8001", "Zürich"), ("3011", "Bern"), ("4051", "Basel"), ("1201", "Genève"), ("6003", "Luzern")], ["Bahnhofstrasse", "Marktgasse", "Seestrasse", "Dorfstrasse", "Hauptstrasse"], "ch"),
    "103": ([("1000", "Bruxelles"), ("2000", "Antwerpen"), ("9000", "Gent"), ("3000", "Leuven"), ("4000", "Liège")], ["Rue Neuve", "Meir", "Veldstraat", "Bondgenotenlaan", "Rue de la Loi"], "be"),
    "105": ([("1012 AB", "Amsterdam"), ("3011 AA", "Rotterdam"), ("2511 BT", "Den Haag"), ("3511 LX", "Utrecht"), ("5611 AA", "Eindhoven")], ["Kalverstraat", "Coolsingel", "Lange Voorhout", "Oudegracht", "Stratumseind"], "nl"),
    "233": ([("1009", "Luxembourg"), ("4001", "Esch-sur-Alzette"), ("9001", "Ettelbruck")], ["Grand-Rue", "Avenue de la Liberté", "Rue de Hollerich", "Boulevard Royal"], "lu"),
    "106": ([("28013", "Madrid"), ("08002", "Barcelona"), ("41004", "Sevilla"), ("46002", "València"), ("48001", "Bilbao")], ["Calle Mayor", "Gran Vía", "Carrer de Pelai", "Calle Sierpes", "Avenida Diagonal"], "es"),
    "333": ([("SW1A 1AA", "London"), ("M1 1AE", "Manchester"), ("B1 1AA", "Birmingham"), ("EH1 1YZ", "Edinburgh"), ("LS1 1UR", "Leeds")], ["High Street", "Station Road", "Church Lane", "Victoria Road", "King Street"], "co.uk"),
    "102": ([("75001", "Paris"), ("69001", "Lyon"), ("13001", "Marseille"), ("33000", "Bordeaux"), ("59000", "Lille"), ("67000", "Strasbourg")], ["Rue de Rivoli", "Avenue Jean Jaurès", "Rue Nationale", "Boulevard Victor Hugo", "Rue de la République"], "fr"),
    "214": ([("00184", "Roma"), ("20121", "Milano"), ("80134", "Napoli"), ("10121", "Torino"), ("40121", "Bologna"), ("50123", "Firenze")], ["Via Roma", "Corso Vittorio Emanuele", "Via Garibaldi", "Via Dante", "Piazza del Duomo"], "it"),
    "108": ([("1010", "Wien"), ("8010", "Graz"), ("4020", "Linz"), ("5020", "Salzburg"), ("6020", "Innsbruck")], ["Mariahilfer Straße", "Herrengasse", "Landstraße", "Getreidegasse", "Maria-Theresien-Straße"], "at"),
    "101": ([], [], "de"),
}
# European mix in percent (DE-heavy like a German shop, but broad)
MIX = [("101", 38), ("108", 9), ("107", 5), ("105", 6), ("103", 4), ("233", 1), ("102", 7), ("214", 7), ("106", 5), ("281", 2),
       ("280", 4), ("166", 3), ("167", 3), ("313", 3), ("181", 1), ("269", 1), ("212", 1), ("206", 1), ("192", 1), ("285", 1), ("333", 2)]
pool = [c for c, w in MIX for _ in range(w)]

def address(c):
    bi = BUILTIN.get(c)
    sample_places, sample_streets = places.get(c, []), streets.get(c, [])
    if sample_places and (len(sample_places) >= 20 or not bi or not bi[0]):
        postal, city = random.choice(sample_places)
    else:
        postal, city = random.choice(bi[0])
    st_pool = (sample_streets if len(sample_streets) >= 20 else []) or (bi[1] if bi else []) or streets.get("101", [])
    street = f"{random.choice(st_pool)} {random.randint(1, 120)}{random.choice(['', '', '', 'a', 'b'])}"
    return street, postal, city, (bi[2] if bi else "eu")

rows, seen = [], set()
while len(rows) < N:
    f, s = random.choice(first), random.choice(last)
    if (f, s) in seen: continue
    seen.add((f, s))
    c = random.choice(pool); street, postal, city, tld = address(c)
    mail = re.sub(r"[^a-z.]", "", f"{f}.{s}".lower().replace("ä", "ae").replace("ö", "oe").replace("ü", "ue").replace("ß", "ss")) + "@example." + tld
    rows.append({"name": f"{f} {s}", "street": street, "postal": postal, "city": city, "countryId": int(c), "email": mail})
random.shuffle(rows)
json.dump(rows, open(out, "w", encoding="utf-8"), ensure_ascii=False, indent=0)
print(len(rows), "consignees; countries:", dict(sorted(Counter(r["countryId"] for r in rows).items())))
print("initials:", "".join(sorted({r["name"][0] for r in rows})))
