"""Calculate a signed-current pair; illustrative analysis, no instrument control."""
import argparse
import csv
import math
from pathlib import Path

INPUT_FIELDS = ('i_plus_mA', 'i_minus_mA', 'v_plus_uV', 'v_minus_uV')
OUTPUT_FIELDS = ('r_pair_mohm', 'offset_pair_uV', 'calculation_status', 'calculation_note')


def calculate(row):
    if any(row.get(key) is None or not str(row.get(key, '')).strip() for key in INPUT_FIELDS):
        return {'r_pair_mohm': '', 'offset_pair_uV': '', 'calculation_status': 'missing',
                'calculation_note': 'Missing readings; no zero imputation.'}
    try:
        ip, im, vp, vm = (float(row[key]) for key in INPUT_FIELDS)
    except (ValueError, TypeError):
        return {'r_pair_mohm': '', 'offset_pair_uV': '', 'calculation_status': 'invalid',
                'calculation_note': 'Readings must be numeric.'}
    if not all(math.isfinite(x) for x in (ip, im, vp, vm)) or not (ip > 0 and im < 0):
        return {'r_pair_mohm': '', 'offset_pair_uV': '', 'calculation_status': 'invalid',
                'calculation_note': 'Require finite readings and Iplus>0, Iminus<0.'}
    resistance = (vp - vm) / (ip - im)
    offset = vp - ip * resistance
    if not math.isfinite(resistance) or not math.isfinite(offset):
        return {'r_pair_mohm': '', 'offset_pair_uV': '', 'calculation_status': 'invalid',
                'calculation_note': 'Non-finite calculated output.'}
    return {'r_pair_mohm': format(resistance, '.12g'), 'offset_pair_uV': format(offset, '.12g'),
            'calculation_status': 'calculated',
            'calculation_note': 'Assumes a linear resistor and stable offset. No acceptance judgment.'}


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('input_csv')
    parser.add_argument('output_csv')
    args = parser.parse_args()
    if Path(args.input_csv).resolve() == Path(args.output_csv).resolve():
        parser.error('Use a different output file to preserve raw readings.')
    with open(args.input_csv, encoding='utf-8-sig', newline='') as source:
        reader = csv.DictReader(source)
        if not reader.fieldnames or not set(INPUT_FIELDS).issubset(reader.fieldnames):
            parser.error('Input lacks the four signed-reading columns.')
        fields = [x for x in reader.fieldnames if x not in OUTPUT_FIELDS] + list(OUTPUT_FIELDS)
        rows = [{**row, **calculate(row)} for row in reader]
    with open(args.output_csv, 'w', encoding='utf-8-sig', newline='') as target:
        writer = csv.DictWriter(target, fieldnames=fields)
        writer.writeheader()
        writer.writerows(rows)


if __name__ == '__main__':
    main()
