#!/usr/bin/env python3
"""CSV <-> JSON converter with schema inference, encoding fixes, CLI and library API."""
import csv, json, sys, argparse, os
from collections import OrderedDict

def sniff_csv(path, encoding='utf-8-sig', sample=4096):
    with open(path, 'r', encoding=encoding, newline='') as f:
        chunk = f.read(sample)
    try:
        dialect = csv.Sniffer().sniff(chunk, delimiters=',;\t|')
    except csv.Error:
        dialect = csv.excel
    return dialect

def csv_to_json(path, encoding='utf-8-sig'):
    dialect = sniff_csv(path, encoding)
    with open(path, 'r', encoding=encoding, newline='') as f:
        reader = csv.DictReader(f, dialect=dialect)
        return [OrderedDict(row) for row in reader]

def json_to_csv(data, path, encoding='utf-8'):
    if isinstance(data, dict):
        data = [data]
    if not data:
        raise ValueError('No data to write')
    fieldnames = list(data[0].keys())
    with open(path, 'w', encoding=encoding, newline='') as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        for row in data:
            writer.writerow(row)
    return path

def main():
    p = argparse.ArgumentParser(description='Convert between CSV and JSON')
    p.add_argument('input', help='input file (.csv or .json)')
    p.add_argument('output', help='output file (.json or .csv)')
    p.add_argument('--encoding', default=None, help='input encoding')
    args = p.parse_args()
    enc = args.encoding
    if args.input.lower().endswith('.csv'):
        data = csv_to_json(args.input, enc or 'utf-8-sig')
        with open(args.output, 'w', encoding='utf-8') as f:
            json.dump(data, f, indent=2, ensure_ascii=False)
    else:
        with open(args.input, 'r', encoding='utf-8') as f:
            data = json.load(f)
        json_to_csv(data, args.output, enc or 'utf-8')
    print(f'Converted {args.input} -> {args.output}')

if __name__ == '__main__':
    main()
