#!/usr/bin/env python3
"""Trim CSV cells, normalize email, and keep the first nonblank email.

Usage: python clean-records.py input.csv NEW-output.csv
Requires row_id,name,email columns. Extra columns are preserved.
The input is never modified; an existing output is never overwritten.
"""
import argparse
import csv
import json
from pathlib import Path


def clean(source, destination):
    source, destination = Path(source), Path(destination)
    with source.open(newline='', encoding='utf-8-sig') as handle:
        reader = csv.DictReader(handle, strict=True)
        fields = reader.fieldnames or []
        if len(fields) != len(set(fields)) or not {'row_id', 'name', 'email'} <= set(fields):
            raise ValueError('Use unique headers including row_id,name,email.')
        rows = []
        seen = set()
        total = duplicates = blank = 0
        for record in reader:
            total += 1
            if None in record or any(value is None for value in record.values()):
                raise ValueError(f'Row {total + 1} has the wrong number of columns.')
            record = {key: value.strip() for key, value in record.items()}
            record['email'] = record['email'].lower()
            if not record['email']:
                blank += 1
            elif record['email'] in seen:
                duplicates += 1
                continue
            else:
                seen.add(record['email'])
            rows.append(record)
    # Exclusive creation also blocks an existing symlink or the source path.
    with destination.open('x', newline='', encoding='utf-8') as handle:
        writer = csv.DictWriter(handle, fieldnames=fields, lineterminator='\n')
        writer.writeheader()
        writer.writerows(rows)
    return {'input_rows': total, 'output_rows': len(rows), 'duplicates_removed': duplicates, 'blank_email_rows_kept': blank}


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('input_csv')
    parser.add_argument('new_output_csv')
    args = parser.parse_args()
    try:
        print(json.dumps(clean(args.input_csv, args.new_output_csv)))
    except (OSError, ValueError, csv.Error) as error:
        parser.exit(1, f'No successful cleanup: {error}\n')
