#!/usr/bin/env python3
import csv
import os
import argparse
import textwrap
import html

# version 0.6 2026-04-18

def check_delimiter(file_path):
    # check for delimiter ';' or ','
    with open(file_path, "r", encoding="utf-8") as f:
        sample = f.read(2048)
        sniffer = csv.Sniffer()
        dialect = sniffer.sniff(sample, delimiters=";,")
        return dialect.delimiter


def csv_to_html_rows(csv_file, compact=False, wrap=None):
    delimiter = check_delimiter(csv_file)

    html_rows = []
    with open(csv_file, newline='', encoding="utf-8") as f:
        reader = csv.reader(f, delimiter=delimiter)

        for row in reader:
            if not row:
                continue

            if compact:
                cells = [f"<td>{html.escape(cell)}</td>" for cell in row]
                if wrap is None:
                    row_html = f"<tr>{''.join(cells)}</tr>"
                else:
                    current_line = "<tr>"
                    lines = []

                    for cell in cells:
                        if len(current_line) + len(cell) > wrap:
                            lines.append(current_line)
                            current_line = cell
                        else:
                            current_line += cell

                    current_line += "</tr>"
                    lines.append(current_line)

                    row_html = "\n".join(lines)
                html_rows.append(row_html)
            else:
                cells = "\n".join(f"  <td>{html.escape(cell)}</td>" for cell in row)
                row_html = f"<tr>\n{cells}\n</tr>"
                html_rows.append(row_html)
        wrapped_rows = []
        for row_final in html_rows:
            if not row_final:
                continue
            if wrap is not None:
                lines = row_final.split("\n")
                wrapped_lines = [
                    textwrap.fill(line, width=wrap-1, break_long_words=False)
                    for line in lines]
                cell = "\n".join(wrapped_lines)
            else:
                cell = row_final
            wrapped_rows.append(cell)
    return wrapped_rows


def main():
    # make sure here wrap to work
    parser = argparse.ArgumentParser(description="Convert CSV to HTML table rows", color=False)
    parser.add_argument("--input", help="name of input CSV file", required=True)
    parser.add_argument("--output", help="name of output HTML file")
    parser.add_argument("--compact", action="store_true",
                        help="output fewer newlines")
    parser.add_argument("--wrap", nargs="?", default=None, const=72, type=int, metavar="WIDTH",
                        help="wrap output at 72 columns (or WIDTH)")

    args = parser.parse_args()
    csv_file = args.input

    html_rows = csv_to_html_rows(csv_file, args.compact, args.wrap)
    if args.output:
        output_file = args.output if args.output.endswith(".html") else args.output + ".html"
    else:
        output_file = os.path.splitext(csv_file)[0] + ".html"

    with open(output_file, "w", encoding="utf-8") as f:
        f.write("\n".join(html_rows))

    print(f"html saved to: {output_file}")


if __name__ == "__main__":
    main()
